參考
建議大家先使用demo實(shí)驗(yàn),成功后再集成到真正項(xiàng)目中。。。因?yàn)?。。。你懂的?。。?/h1>
寫在前面
好久沒(méi)有寫博客了,都用筆記的形式記錄了所學(xué)的東西。最近面試跟面試官聊起,發(fā)現(xiàn)寫博客真的是一個(gè)好習(xí)慣,希望堅(jiān)持下去吧。本文的目的就一個(gè),讓應(yīng)用接入Tinker熱更新,我們不去探究這東西怎么實(shí)現(xiàn),本文僅僅作為工具使用指南。
類似的原理性文章可以參考下拙作:
Android黑科技動(dòng)態(tài)加載(一)之Java中的ClassLoader
Android黑科技動(dòng)態(tài)加載(二)之Android中的ClassLoader
Android黑科技動(dòng)態(tài)加載(三)之動(dòng)態(tài)加載資源
Android黑科技動(dòng)態(tài)加載(四)之插件化開發(fā)
基準(zhǔn)包
例如有一個(gè)版本A,但是這時(shí)A是有Bug的,然后修復(fù)Bug后的生成的版本我們稱為B。A和B之間的區(qū)別產(chǎn)生一個(gè)差分包(這里也稱為補(bǔ)丁包),那么我們就可以說(shuō)這個(gè)差分包是以A作為基準(zhǔn)包相對(duì)B生成的。參考增量更新文章:Android NDK開發(fā)兩部曲(二)之應(yīng)用篇(增量更新也就那樣)
基本步驟
1、注冊(cè)Tinker賬號(hào)并新建項(xiàng)目,傳送門
2、配置gradle和代碼
3、生成基準(zhǔn)包
4、修復(fù)Bug
5、生成補(bǔ)丁包
6、發(fā)布補(bǔ)丁包
Tinker做了什么
1、1-2步是APP開發(fā)的基本步驟,完成1-3步,那么你的APP就集成了Tinker。
集成Tinker后,Tinker會(huì)根據(jù)各個(gè)版本的配置信息去自動(dòng)加載補(bǔ)丁。可配置強(qiáng)制更新,也可配置輪詢更新。
2、第3步則是保留一個(gè)之前版本副本,用于后面生成補(bǔ)丁。為什么要這樣做?因?yàn)?.0.2的相對(duì)于1.0.1的補(bǔ)丁包只能作用在1.0.1版本上。如果想要處理1.0.0那么有兩種方法,使用1.0.0->1.0.1和1.0.1->1.0.2兩個(gè)補(bǔ)丁包。但是也可以生成1.0.0->1.0.2的補(bǔ)丁包。所以副本保留還是有必要的。
3、4-6部就是真正應(yīng)用到生產(chǎn)環(huán)境上了,真正達(dá)到熱修復(fù)的作用。
一、注冊(cè)Tinker賬號(hào)
這個(gè)就不說(shuō)了,Tinker注冊(cè)和新建項(xiàng)目都好簡(jiǎn)單,也沒(méi)有什么需要注意的。拿到appKey
二、配置Gradle和代碼
這個(gè)推薦我們的拷貝粘貼代碼
1、配置Tinker版本信息
我們使用配置文件去配置版本信息,易于統(tǒng)一版本和后面更換版本
編輯根目錄的gradle.properties,加入
TINKER_VERSION=1.9.2
TINKERPATCH_VERSION=1.2.2
2、配置根目錄下的build.gradle文件
使用Tinker插件
classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:${TINKERPATCH_VERSION}"
3、配置Tinker的gradle腳本
在項(xiàng)目根目錄新建tinkerpatch.gradle文件
apply plugin: 'tinkerpatch-support'
/**
* TODO: 請(qǐng)按自己的需求修改為適應(yīng)自己工程的參數(shù)
*/
def bakPath = file("${buildDir}/bakApk/")
def baseInfo = "app-1.0.0-1213-19-52-36"
def variantName = "release"
/**
* 對(duì)于插件各參數(shù)的詳細(xì)解析請(qǐng)參考
* http://tinkerpatch.com/Docs/SDK
*/
tinkerpatchSupport {
/** 可以在debug的時(shí)候關(guān)閉 tinkerPatch **/
/** 當(dāng)disable tinker的時(shí)候需要添加multiDexKeepProguard和proguardFiles,
這些配置文件本身由tinkerPatch的插件自動(dòng)添加,當(dāng)你disable后需要手動(dòng)添加
你可以copy本示例中的proguardRules.pro和tinkerMultidexKeep.pro,
需要你手動(dòng)修改'tinker.sample.android.app'本示例的包名為你自己的包名, com.xxx前綴的包名不用修改
**/
tinkerEnable = true
reflectApplication = true
/**
* 是否開啟加固模式,只能在APK將要進(jìn)行加固時(shí)使用,否則會(huì)patch失敗。
* 如果只在某個(gè)渠道使用了加固,可使用多flavors配置
**/
protectedApp = false
/**
* 實(shí)驗(yàn)功能
* 補(bǔ)丁是否支持新增 Activity (新增Activity的exported屬性必須為false)
**/
supportComponent = true
autoBackupApkPath = "${bakPath}"
appKey = "c6a00cf4aafa2ab2"
/** 注意: 若發(fā)布新的全量包, appVersion一定要更新 **/
appVersion = "1.0.0"
def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
def name = "${project.name}-${variantName}"
baseApkFile = "${pathPrefix}/${name}.apk"
baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
baseResourceRFile = "${pathPrefix}/${name}-R.txt"
/**
* 若有編譯多flavors需求, 可以參照: https://github.com/TinkerPatch/tinkerpatch-flavors-sample
* 注意: 除非你不同的flavor代碼是不一樣的,不然建議采用zip comment或者文件方式生成渠道信息(相關(guān)工具:walle 或者 packer-ng)
**/
}
/**
* 用于用戶在代碼中判斷tinkerPatch是否被使能
*/
android {
defaultConfig {
buildConfigField "boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}"
}
}
/**
* 一般來(lái)說(shuō),我們無(wú)需對(duì)下面的參數(shù)做任何的修改
* 對(duì)于各參數(shù)的詳細(xì)介紹請(qǐng)參考:
* 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
}
}
注意幾個(gè)字段內(nèi)容,主要是后面生成補(bǔ)丁需要用到的,除了AppKey外其他暫時(shí)不用改
baseInfo : 這個(gè)是基準(zhǔn)包的名稱,使用Tinker腳本編譯在模塊的build/bakApk生成編譯副本
variantName : 這個(gè)一般對(duì)應(yīng)buildTypes里面你基準(zhǔn)包生成的類型,release、debug或其他
appKey : 這個(gè)就是Tinker新建項(xiàng)目時(shí)拿到的appKey
appVersion : 配置和Tinker后臺(tái)新建補(bǔ)丁包的一致
4、配置模塊下的buidle.gradle
A、配置應(yīng)用簽名
這個(gè)百度搜都有,大概就這樣
signingConfigs {
release {//發(fā)布版本的簽名配置
storeFile file('key.jks')
keyAlias 'test'
storePassword '123456789'
keyPassword '123456789'
}
debug {//調(diào)試版本的簽名配置
storeFile file('key.jks')
keyAlias 'test'
storePassword '123456789'
keyPassword '123456789'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.debug
}
}
B、配置依賴
//若使用annotation需要單獨(dú)引用,對(duì)于tinker的其他庫(kù)都無(wú)需再引用
annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {
changing = true
}
compileOnly("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {
changing = true
}
implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:${TINKERPATCH_VERSION}") {
changing = true
}
C、使用插件
在模塊的build.gradle加入
apply from: 'tinkerpatch.gradle'
3、代碼配置
最后一步配置,把代碼集成到App里,別忘了在AndroidManifest里面配置APP。。。
public class App extends Application {
private ApplicationLike tinkerApplicationLike;
@Override
public void onCreate() {
super.onCreate();
tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
// 初始化TinkerPatch SDK, 更多配置可參照API章節(jié)中的,初始化SDK
TinkerPatch.init(tinkerApplicationLike)
.reflectPatchLibrary()
.fetchPatchUpdate(true)
// 強(qiáng)制更新
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.setFetchPatchIntervalByHours(3);
// 每隔3個(gè)小時(shí)(通過(guò)setFetchPatchIntervalByHours設(shè)置)去訪問(wèn)后臺(tái)時(shí)候有更新,通過(guò)handler實(shí)現(xiàn)輪訓(xùn)的效果
TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
}
}
三、生成基準(zhǔn)包
其實(shí)到了這里就配置完成了,我們生產(chǎn)一個(gè)基準(zhǔn)包

雙擊assembleRelease生成成功后安裝模塊/build/outputs/apk/release/app-release.apk就OK了,這時(shí)候進(jìn)去模塊/build/bakApk里面記錄一下類似app-1.0.0-1213-19-52-36的文件名稱,只生成一次基準(zhǔn)包,那么就會(huì)生成一個(gè)。但是如果手賤點(diǎn)太多生成太多的話確定不了剛剛生成的是哪個(gè),那么就選最新那個(gè)或者刪掉重新生成基準(zhǔn)包,真實(shí)環(huán)境并不允許這樣搞。。。


四、修復(fù)bug
隨便修改點(diǎn)代碼
五、生成補(bǔ)丁包
這時(shí)候我們就需要去修改一些tinkerpatch.gradle文件的信息了。
baseInfo :還記得app-1.0.0-1213-19-52-36這個(gè)東西嗎?換成自己上面記錄的就OK了
variantName : 因?yàn)閯倓偽覀兪褂?code>assembleRelease生成的補(bǔ)丁,所以我們只需要使用release就OK了

雙擊TinkerPatchRelease生成差分包,patch_signed_7zip.apk就是補(bǔ)丁包了

六、發(fā)布補(bǔ)丁包
回到Tinker后臺(tái),選中我們開始新建的項(xiàng)目,補(bǔ)丁下發(fā)->添加APP版本。然后上傳剛剛的patch_signed_7zip.apk。

APP開啟強(qiáng)制更新的話那么重啟應(yīng)用就會(huì)更新,否則會(huì)通過(guò)輪詢?nèi)ジ隆?yīng)用重啟才生效。Tinker太強(qiáng)大了,本文目的就是把項(xiàng)目跑通,相信后面的很多功能大家有興趣的話一起發(fā)現(xiàn),一起討論。