熱更新Tinker的整合使用
請珍惜勞動者的汗水,一分耕耘一分收穫,轉載請註明出處,謝謝!
初衷:如今熱更新越來越火,各大廠也陸續開源自己的熱更新框架。目前主流的熱更新大概有以下一些,未統計到的望給予補充。
正好年底了有點時間,也總結一下。
1、Tinker
微信 2、QZone QQ空間 3、阿里 AndFix 4、美團 Robust 5、Nuwa 俗稱女媧 。。。。。。
下面就本人用到的Tinker做個分析,以及具體的實現步驟。
傻瓜式SDK Tinker進入參考文件:http://tinkerpatch.com/Docs/intro
當然還要一種是原始碼直接接入,自己管理後臺服務,稍微複雜麻煩點,可參考github上Tinker的官方介紹:https://github.com/Tencent/tinker
具體的原理和差異演算法大家可以去參考下官方文件
差異演算法結構圖:
對比以上各優勢果斷選擇了Tinker,主要看中的是資原始檔的替換,當然有一點不滿意的就是無法及時生效,不過也不影響,還可以使用鎖屏自動生效的方式,這一點還是挺好的!
2、整合步驟:
新建專案成功後配置build.gradle,有三處的gradle需要配置。由於文件並未完全標明,其中一個gradle的配置還是費了點精力^_^。最後還是再同事的一句話點醒了。
2.1 至於我們的Application可以使用我們平常專案中正常的方式,只需稍加蓋上即可。
public class SampleApplication extendsApplication{ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); TinkerPatch.init(TinkerPatchApplicationLike.getTinkerPatchApplicationLike()); TinkerPatch tinkerPatch = TinkerPatch.with(); tinkerPatch.fetchPatchUpdate(true); //向後臺請求補丁升級配置;true,即每次呼叫都會真正的訪問後臺是否有更新。} }
gradle結構:
都需要我們配置,其中tinkerpatch.gradle 需要手動建立,然後在 2 中進行引用
具體看下第1個 的內容:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' // TinkerPatch 外掛 classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.0.1" } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
下面先看下 第3個 gradle的內容:
apply plugin: 'tinkerpatch-support' def bakPath = file("${buildDir}/basekApk/") def tempPath = "app-1.0.0-0113-10-26-03" /** * 對於外掛各引數的詳細解析請參考 * http://tinkerpatch.com/Docs/SDK */ tinkerpatchSupport { tinkerEnable = true appKey = "你要去申請的appkey" appVersion = "${APP_VERSIONNAME}" reflectApplication = true autoBackupApkPath = "${bakPath}" baseApkFile = "${bakPath}/${tempPath}/app-release.apk" //app-debug.apk baseProguardMappingFile = "${bakPath}/${tempPath}/app-release-mapping.txt" //app-debug-mapping.txt baseResourceRFile = "${bakPath}/${tempPath}/app-release-R.txt" //app-debug-R.txt } /** * 一般來說,我們無需對下面的引數做任何的修改 * 對於各引數的詳細介紹請參考: * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97 */ tinkerPatch { ignoreWarning = false useSign = true dex { dexMode = "jar" pattern = ["classes*.dex"] loader = [] } lib { pattern = ["lib/*/*.so"] } res { pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"] ignoreChange = [] largeModSize = 100 } packageConfig { } sevenZip { zipArtifact = "com.tencent.mm:SevenZip:1.1.10" // path = "/usr/local/bin/7za" } buildConfig { keepDexApply = false } }
很簡單
繼續第2點,也沒啥好將的,就是需要將第3個gradle進行apply
apply from: 'tinkerpatch.gradle'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.0'
testCompile 'junit:junit:4.12'
compile "com.android.support:multidex:1.0.1"
//若使用annotation需要單獨引用,對於tinker的其他庫都無需再引用
provided("com.tencent.tinker:tinker-android-anno:1.7.6") { changing = true }
compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.0.1"){ changing = true }
}
至此Tinker的整合已經搞定!!!下面就是打包,編譯差異包的過程了。下面還是列下官方的實現步驟吧,依葫蘆畫瓢,so sasy !
參考:http://tinkerpatch.com/Docs/SDK
整合完畢後將專案切換到Project模式下,可以看到這樣的結構
展開Gradle projects 編譯打包,其中tinker下是編譯產生差異包
第一步 新增 gradle 外掛依賴
gradle 遠端倉庫依賴 jcenter, 例如 TinkerPatch Sample 中的build.gradle.buildscript {
repositories {
jcenter()
}
dependencies {
// TinkerPatch 外掛
classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.0.2"
}
}
注意,在這裡SDK使用了fat打包的模式,我們不能再引入任何 Tinker 的相關依賴,否則會造成版本衝突。當前SDK是基於 tinker 1.7.6 核心開發的。第二步 整合 TinkerPatch SDK
新增TinkerPatch SDK 庫的 denpendencies 依賴, 可參考 Sample 中的 app/build.gradle:
dependencies {
//若使用annotation需要單獨引用,對於tinker的其他庫都無需再引用
provided("com.tencent.tinker:tinker-android-anno:1.7.6")
compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.0.2")
}
注意,若使用 annotation 自動生成 Application, 需要單獨引入 Tinker的 tinker-android-anno 庫。除此之外,我們無需再單獨引入 tinker 的其他庫。
為了簡單方便,我們將 TinkerPatch 相關的配置都放於 tinkerpatch.gradle 中, 我們需要將其引入:
apply from: 'tinkerpatch.gradle'
第三步 配置 tinkerpatchSupport 引數
開啟引入的 tinkerpatch.gradle 檔案,它的具體引數如下:
tinkerpatchSupport {
tinkerEnable = true
appKey = "f828475486f91936"
appVersion = "1.0.0"
autoBackupApkPath = "${bakPath}"
baseApkFile = "${bakPath}/${appName}/app-debug.apk"
baseProguardMappingFile = "${bakPath}/${appName}/app-debug-mapping.txt"
baseResourceRFile = "${bakPath}/${appName}/app-debug-R.txt"
}
它的具體含義如下:
引數 | 預設值 | 描述 |
---|---|---|
tinkerEnable | true | 是否開啟 tinkerpatchSupport 外掛功能。 |
appKey | "" | 在 TinkerPatch 平臺 申請的 appkey, 例如 sample 中的 'f828475486f91936' |
appVersion | "" | 在 TinkerPatch 平臺 輸入的版本號, 例如 sample 中的 '1.0.0'。 注意,我們使用 appVersion 作為 TinkerId, 我們需要保證每個釋出出去的基礎安裝包的 appVersion 都不一樣。 |
reflectApplication |
false | 是否反射 Application 實現一鍵接入;一般來說,接入 Tinker 我們需要改造我們的 Application, 若這裡為 true, 即我們無需對應用做任何改造即可接入。 |
autoBackupApkPath | "" | 將每次編譯產生的 apk/mapping.txt/R.txt 歸檔儲存的位置 |
baseApkFile | "" | 基準包的檔案路徑,
對應 tinker 外掛中的 oldApk 引數 ;編譯補丁包時,必需指定基準版本的 apk,預設值為空,則表示不是進行補丁包的編譯。 |
baseProguardMappingFile | "" | 基準包的
Proguard mapping.txt 檔案路徑, 對應 tinker 外掛 applyMapping 引數 ;在編譯新的 apk 時候,我們希望通過保持基準 apk 的 proguard 混淆方式,從而減少補丁包的大小。這是強烈推薦的,編譯補丁包時,我們推薦輸入基準 apk 生成的 mapping.txt 檔案。 |
baseResourceRFile | "" | 基準包的資源
R.txt 檔案路徑, 對應 tinker 外掛 applyResourceMapping 引數 ;在編譯新的apk時候,我們希望通基準 apk 的 R.txt 檔案來保持 Resource Id 的分配,這樣不僅可以減少補丁包的大小,同時也避免由於 Resource Id 改變導致 remote view 異常。 |
一般來說,我們無需修改引用 android 的編譯配置,也不用修改 tinker 外掛原來的配置。針對特殊需求,具體的引數含義可參考 Tinker 文件:Tinker 接入指南.
第四步 初始化 TinkerPatch SDK
最後在我們的程式碼中,只需簡單的初始化 TinkerPatch 的 SDK 即可,我們無需考慮 Tinker 是如何下載/合成/應用補丁包, 也無需引入各種各樣 Tinker 的相關類。
1. reflectApplication = true 的情況
若我們使用 reflectApplication 模式,我們無需為接入 Tinker 而改造我們的 Application 類。初始化 SDK 可參考 tinkerpatch-easy-sample 中的 SampleApplication 類.
public class SampleApplication extends Application {
...
public void attachBaseContext(Context base) {
TinkerPatch.init(TinkerPatchApplicationLike.getTinkerPatchApplicationLike());
}
...
我們將 Tinker 載入補丁過程的結果存放在 TinkerPatchApplicationLike 中。
2. reflectApplication = false 的情況
若我們已經完成了應用的 Application 改造,即將 Application 的邏輯移動到 ApplicationLike類中。我們可以參考 tinkerpatch-sample 中的 SampleApplicationLike 類.
public class SampleApplicationLike extends DefaultApplicationLike {
...
public void onBaseContextAttached(Context base) {
TinkerPatch.init(this);
}
...
}
第五步 使用步驟
TinkerPatch 的使用步驟非常簡單,一般來說可以參考以下幾個步驟:
- 執行
assembleRelease
task 構建基準包,即將要釋出的版本; - 通過
autoBackupApkPath
儲存編譯的產物 apk/mapping.txt/R.txt 檔案; - 若想釋出補丁包, 只需將步驟2儲存下來的檔案分別填到
baseApkFile
/baseProguardMappingFile
/baseResourceRFile
引數中; - 執行
tinkerPatchRelease
task 構建補丁包,補丁包將位於build/outputs/tinkerPatch
中。
搞定!
後面就是將差異包提交的Tinker的Web上了。
差異包的釋出可根據需要選擇條件,不再囉嗦了。大家可以自己去看下介紹,沒什麼難度。有不懂的可以直接評論,第一次寫這麼長的部落格,自我感覺都很爛,但這是一個鍛鍊的過程,而且沒有足夠的時間來總結,只是碰巧今天又點時間就先寫上來了。公司一直都忙忙忙啊!!!!!受不了了,再看看咱們的IOS多爽,3個月沒做過專案,爽死了!不過誰叫我們是Android屌絲呢^_^,吐槽歸吐槽,還是要把工作幹好!最後期待18號年會能給我抽個大獎啊!!!
各位見笑了,有問題Call我,能解決的一定盡力,幫不到的一起努力!祝自己2017工作順利,身體健康,家庭和睦!祝大家步步高昇!