Android熱更新開源項目Tinker集成實踐總結(jié)
前言
最近項目集成了Tinker,開始認(rèn)為集成會比較簡單,但是在實際操作的過程中還是遇到了一些問題,本文就會介紹在集成過程大家基本會遇到的主要問題。
考慮一:后臺的選取
目前后臺功能可以通過三種方式實現(xiàn):
1、自己搭建后臺布丁下發(fā)系統(tǒng)
2、第三方提供的服務(wù),目前如原微信simsun大神的個人tinkerpatch平臺,目前出于內(nèi)測階段,暫時免費。后期應(yīng)該會按下發(fā)量對app進(jìn)行收費。
3、騰訊Bugly提供的服務(wù),提供了熱更新的下發(fā)后臺,集成到了bugly的升級sdk中。免費。
根據(jù)公司的精神,我們選擇了Bugly作為我們的方案,這個大家都懂得。
考慮二:多渠道打包的問題
我們有將近100個渠道,每個渠道需要一個不同的渠道號,按product flavor的方式打出來的包的dex都有差異。這樣就造成100個渠道包的熱更新就需要100個補(bǔ)丁,這對管理簡直是一個災(zāi)難。Tinker也對這種問題給出了推薦的方案,那就是使用開源項目packer-ng-plugin,它的原理是將渠道信息寫在apk文件的zip comment中,這樣在多渠道打包時就不會影響dex的內(nèi)容。
考慮三:資源混淆所造成的問題
目前項目使用了資源混淆項目AndResGuard,關(guān)于AndResGuard的介紹,可以參考文檔AndResGuard[Android混淆工具AndResGuard]。
也正是引入了資源混淆,熱更新和多渠道打包都必須依賴資源混淆后生成的apk包才行。所以我們對編譯流程進(jìn)行了整合。
**整合前**
編譯:編譯直接使用AndResGuard提供的命令resguardRelease生成即可。resguardRelease生成的apk文件是沒有資源混淆的。
./gradlew resguardRelease
Tinker生成補(bǔ)?。褐苯诱{(diào)用tinkerPatchRelease任務(wù)生成的Release文件沒有進(jìn)行資源混淆
./gradlew tinkerPatchRelease
多渠道打包:使用packer-ng的命令apkRelease生成多渠道文件沒有進(jìn)行資源混淆
./gradlew apkRelease
**整合后**
主要解決兩個問題:
1、Tinker生成補(bǔ)丁的原始和新的apk,需要使用資源混淆后的apk
2、多渠道打包所使用的原始apk,需要使用資源混淆后的apk
針對問題1:
當(dāng)使用resguardRelease進(jìn)行編譯,在編譯完成后,將生成的apk文件、R文件、map文件和resouce map文件拷貝到${buildDir}/bakApk/resguard目錄下;
當(dāng)使用tinkerPatchRelease生成補(bǔ)丁時,在tinkerPatchRelease任務(wù)前加入resguardTask任務(wù),這樣生成補(bǔ)丁時使用的新舊apk都是資源混淆過的。核心的gradle代碼如下:
android.applicationVariants.all { variant ->
/**
* task type, you want to bak
*/
def taskName = variant.name
tasks.all {
if (variant.buildType.name == 'release') {
if ("tinkerPatch${taskName.capitalize()}".equalsIgnoreCase(it.name)) {
// find resguard task
def resguardTask
tasks.all {
if (it.name.startsWith("resguard")) {
resguardTask = it
}
}
it.doFirst({
// change build apk path
it.buildApkPath = "${buildDir}/outputs/apk/AndResGuard_${project.getName()}-${taskName}/${project.getName()}-${taskName}_signed.apk"
})
// change task dependence to resguard task
it.dependsOn resguardTask
}
if ("resguard${taskName.capitalize()}".equalsIgnoreCase(it.name)) {
it.doLast {
copy {
def date = new Date().format("MMdd-HH-mm-ss")
from "${buildDir}/outputs/apk/AndResGuard_${project.getName()}-${taskName}/${project.getName()}-${taskName}_signed_7zip_aligned.apk"
into file(bakPath.absolutePath + "/resguard")
rename { String fileName ->
fileName.replace("${project.getName()}-${taskName}_signed_7zip_aligned.apk", "${project.getName()}-${taskName}-${date}.apk")
}
from "${buildDir}/outputs/mapping/${taskName}/mapping.txt"
into file(bakPath.absolutePath + "/resguard")
rename { String fileName ->
fileName.replace("mapping.txt", "${project.getName()}-${taskName}-${date}-mapping.txt")
}
from "${buildDir}/intermediates/symbols/${taskName}/R.txt"
into file(bakPath.absolutePath + "/resguard")
rename { String fileName ->
fileName.replace("R.txt", "${project.getName()}-${taskName}-${date}-R.txt")
}
from "${buildDir}/outputs/apk/AndResGuard_${project.getName()}-${taskName}/resource_mapping_${project.getName()}-release.txt"
into file(bakPath.absolutePath + "/resguard")
rename { String fileName ->
fileName.replace("resource_mapping_${project.getName()}-release.txt", "${project.getName()}-${taskName}-${date}-resource_mapping.txt")
}
}
}
}
}
}
針對問題2、在AS中使用apkRelease任務(wù)打包的方式不再適用,可直接使用packer-ng所提供的命令行方式進(jìn)行生成渠道包,經(jīng)過測試,100個渠道包的確在10s左右就能打完,速度相當(dāng)之快。考慮到市場推廣人員會打不同渠道包,后期可做一個簡易工具提供給市場推廣人員。
整合后操作:
編譯:
./gradlew resguardRelease
生成的apk文件放在${app}\build\bakApk\resguard\目錄下
打補(bǔ)丁包:
./gradlew tinkerPatchRelease ./gradlew generateManifestForReleaseTinkerPatch
最終生成的補(bǔ)丁放在${app}\build\outputs\patch\目錄下
多渠道打包:
針對編譯后生成的包,使用packer-ng提供的命令行操作即可
java -jar PackerNg-x.x.x.jar apkFile marketFile outputDir
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關(guān)文章
android中Webview實現(xiàn)截屏三種方式小結(jié)
本篇文章主要介紹了android Webview實現(xiàn)截屏,主要詳解了3種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
Android 自定義ProgressDialog進(jìn)度條對話框用法詳解
ProgressDialog為進(jìn)度對話框。android手機(jī)自帶的對話框顯得比較單一,我們可以通過ProgressDialog來自己定義對話框中將要顯示出什么東西2016-01-01
詳解Android數(shù)據(jù)存儲—使用SQLite數(shù)據(jù)庫
本篇文章主要介紹了詳解Android數(shù)據(jù)存儲—使用SQLite數(shù)據(jù)庫,具有一定的參考價值,有興趣的可以了解一下。2017-03-03
Android 判斷屏幕開關(guān)狀態(tài)方式總結(jié)
這篇文章主要介紹了Android 判斷屏幕開關(guān)狀態(tài)方式總結(jié)的相關(guān)資料,需要的朋友可以參考下2016-10-10
Android開發(fā)實現(xiàn)調(diào)節(jié)屏幕亮度功能
這篇文章主要介紹了Android開發(fā)實現(xiàn)調(diào)節(jié)屏幕亮度功能,涉及Android權(quán)限控制及屏幕亮度相關(guān)屬性操作技巧,需要的朋友可以參考下2018-03-03
Android?EventBus粘性事件實現(xiàn)機(jī)制探究
最近項目做組件化,需要進(jìn)行組件化的通信,有時候可能會出現(xiàn)異步的情況,事件接收方還沒準(zhǔn)備好事件就已經(jīng)發(fā)送過來了,這時候想到了EventBus的粘性事件,這篇文章主要給大家介紹了關(guān)于Android?EventBus粘性事件實現(xiàn)機(jī)制的相關(guān)資料,需要的朋友可以參考下2022-05-05

