大概目錄:
* Tinker 編譯相關(guān)問(wèn)題侯谁?
* Tinker 庫(kù)中有什么類(lèi)是不能修改的瘪菌?
* 什么類(lèi)需要放在主 dex 中?
* 我應(yīng)該使用哪個(gè)作為補(bǔ)丁包下發(fā)朦肘,如何做多次修復(fù)担映?
* 如何對(duì) Library 文件作補(bǔ)犊潮簟?
* 如何對(duì)資源文件作補(bǔ)丁硫麻,為什么有時(shí)候會(huì)提示大量沒(méi)有改變的圖片發(fā)生變更爸邢?
* Tinker 中的 dex 配置 'raw' 與 'jar' 模式應(yīng)該如何選擇?
* 如何兼容多渠道包拿愧?
* tinker 是否兼容加固杠河?
* Google Play 版本是否可以有 Tinker 相關(guān)代碼?
* tinker 與 instant run 的兼容問(wèn)題浇辜?
* 每次編譯我應(yīng)該保留哪些文件券敌,如何兼容 AndResGuard?
* tinkerId 應(yīng)該如何選擇柳洋?
* 如何使生成的補(bǔ)丁包更写纭?
* 關(guān)于使用的 ClassLoader 問(wèn)題熊镣?
* 什么時(shí)候調(diào)用 installTinker卑雁?
* Proguard 5.2.1 applymapping 出現(xiàn) Warning?
* TinkerPatch 補(bǔ)丁管理后臺(tái)與 Tinker 的關(guān)系绪囱?
* Tinker 的最佳實(shí)踐测蹲?
一、Tinker 編譯相關(guān)問(wèn)題鬼吵?
編譯過(guò)程相關(guān)的 issue 請(qǐng)先查看是否是以下情況:
無(wú)法打開(kāi) sample 工程: 請(qǐng)使用單獨(dú)的 IDE 窗口打開(kāi)
tinker-sample-android
工程扣甲;tinkerId is not set
:是因?yàn)闆](méi)有正確地配置 IDE 的git
路徑,若不是通過(guò)clone
方式下載tinker
齿椅,需要本地手動(dòng)commit
一次琉挖。這里你也可以使用其他字符作為tinkerId
;對(duì)于編譯與補(bǔ)丁時(shí)發(fā)生的異常涣脚,請(qǐng)到 Tinker 自定義擴(kuò)展 中查看具體錯(cuò)誤碼的原因粹排。并通過(guò)
"Tinker."
過(guò)濾Tinker
相關(guān)的日志提交到issue
中;若自定義
TinkerResultService
涩澡,請(qǐng)務(wù)必將新的Service
添加到Manifest
中顽耳;權(quán)限問(wèn)題;請(qǐng)務(wù)必已經(jīng)將讀取
sdk
權(quán)限添加到AndroidManifest.xml
中妙同,并且已允許權(quán)限運(yùn)行射富;若使用
DefaultLifeCycle
注解生成 Application,需要將原來(lái) Application 的實(shí)現(xiàn)移動(dòng)到ApplicationLike
中粥帚,并將原來(lái)的 Application 類(lèi)刪掉胰耗;關(guān)于 Application 的改造這一塊大家比較疑惑,這塊請(qǐng)認(rèn)真閱讀自定義 Application 類(lèi)芒涡,大部分的 app 應(yīng)該都能在半小時(shí)內(nèi)完成改造柴灯。
如果出現(xiàn)
Class ref in pre-verified class resolved to unexpected implementation
異常卖漫,請(qǐng)確認(rèn)以下幾點(diǎn):Application中傳入ApplicationLike
的參數(shù)時(shí)是否采用字符串而不是Class.getName
方式;新的 Application 是否已經(jīng)加入到dex loader pattern
中赠群;額外添加到dex loader pattern
中類(lèi)的引用類(lèi)也需要加載到loader pattern
中羊始。
二、Tinker 庫(kù)中有什么類(lèi)是不能修改的查描?
Tinker 庫(kù)中不能修改的類(lèi)一共有 26 個(gè)突委,即 com.tencent.tinker.loader.*
類(lèi)。加上你的 Appliction 類(lèi)冬三,只有 26 個(gè)類(lèi)是無(wú)法通過(guò) Tinker 來(lái)修改的匀油。即使類(lèi)似 Tinker.java
等管理類(lèi),也是可以通過(guò) Tinker 本身來(lái)修改勾笆。
注意敌蚜,在 1.7.6 版本之前,我們需要手動(dòng)將不能修改的類(lèi)添加到 tinkerPatch.dex.loader pattern
中窝爪。對(duì)于 1.7.6 以后的版本會(huì)自動(dòng)生成钝侠。
但是若使用 newApk 或者命令行編譯,需要手動(dòng)添加 Application 類(lèi)與 loader 類(lèi)
三酸舍、什么類(lèi)需要放在主 dex 中?
Tinker 并不干涉你分包與多 dex 的加載邏輯里初,但是你需要確保以下幾點(diǎn):
com.tencent.tinker.loader.*
類(lèi)啃勉,你的 Application 類(lèi)需要在主 dex,并且已經(jīng)在dex.loader
中配置双妨;若你自定義了
TinkerLoader
類(lèi)淮阐,你需要將TinkerLoader
的自定義類(lèi),以及它用的到類(lèi)也放在主 dex刁品,并且已經(jīng)在dex.loader
中配置泣特;ApplicationLike
的繼承類(lèi)也需要放在主 dex 中,但是它無(wú)須在dex.loader
中配置挑随,因?yàn)樗强梢允褂?Tinker 修改的類(lèi)状您。最后,如果你需要在加載其他 dex 之前加載 Tinker 的管理類(lèi)兜挨,你也可以將com.tencent.tinker.*
都加入到主 dex膏孟。你的
ApplicationLike
實(shí)現(xiàn)類(lèi)的直接引用類(lèi)以及在調(diào)用Multidex install
之前加載的類(lèi)也都需要放到主 dex 中。
注意:Tinker 會(huì)自動(dòng)生成需要放在主 dex 的 keep 規(guī)則拌汇。在 1.7.6 版本之前柒桑,你需要手動(dòng)將生成規(guī)則拷貝到自己的 multiDexKeepProguard
文件中。例如 Sample 中的 multiDexKeepProguard file("keep_in_main_dex.txt")
噪舀。在 1.7.6 版本之后魁淳,這里會(huì)通過(guò)腳本自動(dòng)處理飘诗,無(wú)須手動(dòng)填寫(xiě)。
另外界逛,如果 minsdkverion >= 21
昆稿,multiDexEnabled
會(huì)被忽略。我們可以在 build/intermediates/multi-dex
查找最終的 keep
規(guī)則以及結(jié)果仇奶。
四貌嫡、我應(yīng)該使用哪個(gè)作為補(bǔ)丁包下發(fā),如何做多次修復(fù)该溯?
patch_signed_7zip.apk
是已簽名并且經(jīng)過(guò) 7z 壓縮的補(bǔ)丁包岛抄,但是你最好重命名一下,不要讓它以 .apk
結(jié)尾狈茉,這是因?yàn)橛行┻\(yùn)營(yíng)商會(huì)挾持以 .apk
結(jié)尾的資源夫椭。
另外一點(diǎn),我們?cè)诎l(fā)起補(bǔ)丁請(qǐng)求時(shí)氯庆,需要先將補(bǔ)丁包先拷貝到 dataDir 中蹭秋。因?yàn)樵?sdcard 中,補(bǔ)丁包是極其容易被清理軟件刪除堤撵。這里可以參考 UpgradePatchRetry.java 的實(shí)現(xiàn)仁讨。
對(duì)于補(bǔ)丁包的版本問(wèn)題,我們可以在 packageConfig
中增加实昨,例如 sample 中的
packageConfig {
/**
* patch version via packageConfig
*/
configField("patchVersion", "1.0")
}
Tinker 支持對(duì)同一基準(zhǔn)版本做多次補(bǔ)丁修復(fù)洞豁,在生成補(bǔ)丁時(shí),oldApk 依然是已經(jīng)發(fā)布出去的那個(gè)版本荒给。即補(bǔ)丁版本二的 oldApk 不能是補(bǔ)丁版本一丈挟,它應(yīng)該依然是用戶手機(jī)上已經(jīng)安裝的基準(zhǔn)版本。
五志电、如何對(duì) Library 文件作補(bǔ)妒镅省?
當(dāng)前官方并沒(méi)有直接將補(bǔ)丁的 lib 路徑添加到 DexPathList
中挑辆,理論上這樣可以做到程序完全沒(méi)有感知的對(duì) Library 文件作補(bǔ)丁例朱。這里主要是因?yàn)樵诙?abi 的情況下,某些機(jī)器獲取的并不準(zhǔn)確鱼蝉。當(dāng)前對(duì) Library 文件作補(bǔ)丁可參考 Tinker API 概覽茉继,tinker 1.7.7 版本中也提供了一鍵反射的方案給大家選擇。
大家可以根據(jù)自己的項(xiàng)目需要選擇合適的方案蚀乔,事實(shí)上烁竭,無(wú)論是對(duì) Library 還是 Application,官方都是采用盡量少去反射的策略吉挣,這也是為了提高 Tinker 框架的兼容性派撕。上線前婉弹,我們應(yīng)當(dāng)嚴(yán)格測(cè)試補(bǔ)丁是否正確加載了修改后的 So 庫(kù)。
六终吼、如何對(duì)資源文件作補(bǔ)丁镀赌,為什么有時(shí)候會(huì)提示大量沒(méi)有改變的圖片發(fā)生變更?
Tinker 采用全量合成方式實(shí)現(xiàn)資源替換际跪,這里有以下幾點(diǎn)是使用者需要明確的:
remoteView
是無(wú)法修改商佛,例如transition
動(dòng)畫(huà),notification icon
以及桌面圖標(biāo)姆打;對(duì)于資源文件的更新(尤其是
assets
)良姆,需要注意代碼中是否采用直接讀取sourceApk
路徑方式讀取,這樣方式是無(wú)法更新的幔戏;
Tinker 只會(huì)將滿足res pattern
的資源放在最后的合成補(bǔ)丁資源包中玛追。一般為了減少合成資源大小,官方不建議輸入classes.dex
或lib
文件的pattern
闲延;若一個(gè)文件
:assets/classes.dex
痊剖,它既滿足dex pattern
,又滿足res pattern
垒玲。Tinker 只會(huì)處理dex pattern
陆馁,然后在合成資源包會(huì)忽略assets/classes.dex
的變更。library 也是如此合愈。只要資源發(fā)生變成的前提下 Tinker 才會(huì)合成新的資源包叮贩,這一定程度會(huì)增加占 Rom 體積,請(qǐng)?jiān)诳紤]后使用想暗。
注意:若出現(xiàn)資源變更,我們需要使用 applyResourceMapping
方式編譯帘不,這樣不僅可以減少補(bǔ)丁包大小说莫,同時(shí)防止 remote view id
變更造成的異常情況。最后我們應(yīng)該查看編譯過(guò)程中生成的 resources_out.zip
是否滿足我們的要求寞焙。
有時(shí)候會(huì)發(fā)現(xiàn)大量明明沒(méi)有改變的 png
發(fā)現(xiàn)變更储狭,解壓發(fā)現(xiàn)的確兩次編譯這些 png
的 md5 不一致。經(jīng)分析捣郊,aapt
在其中一次編譯將 png
優(yōu)化成 8-bit辽狈,另外一次卻沒(méi)有,從而導(dǎo)致 png
改變了呛牲。如果你們 app 出現(xiàn)了這種情況刮萌,官方建議關(guān)閉 aapt
對(duì) png
的優(yōu)化:
aaptOptions{
cruncherEnabled false
}
若你對(duì)安裝包大小非常 care,可以提前使用命令行工具將所有圖片手動(dòng)優(yōu)化一次娘扩。我們也可以選擇一些有損壓縮工具着茸,獲得更大的壓縮效果壮锻。
如果你確認(rèn) png
并沒(méi)有修改,你可以在 tinker
的配置使用 ignoreChange
來(lái)忽略所有 png
文件的修改涮阔。
res {
ignoreChange = ["*.png"]
}
七猜绣、Tinker 中的 dex 配置 'raw' 與 'jar' 模式應(yīng)該如何選擇?
它們應(yīng)該說(shuō)各有優(yōu)劣勢(shì)敬特,大概應(yīng)該有以下幾條原則:
如果你的
minSdkVersion
小于 14掰邢,那你務(wù)必要選擇 'jar' 模式;以一個(gè)
10M
的 dex 為例伟阔,它壓縮成 jar 大約為4M
辣之,即 'jar' 模式能節(jié)省6M
的 ROM 空間。對(duì)于 'jar' 模式减俏,我們需要驗(yàn)證壓縮包流中 dex 的 md5召烂,這會(huì)更耗時(shí),在小米 2S 上數(shù)據(jù)大約為 'raw' 模式
126 ms
娃承,'jar' 模式為246 ms
奏夫。
因?yàn)樵诤铣蛇^(guò)程中 Tinker 已經(jīng)校驗(yàn)了各個(gè)文件的 Md5,并將它們存放在 /data/data/..
目錄中历筝。默認(rèn)每次加載時(shí) Tinker 并不會(huì)去校驗(yàn) tinker 文件的 Md5酗昼,但是你也可通過(guò)開(kāi)啟 loadVerifyFlag
強(qiáng)制每次加載時(shí)校驗(yàn),但是這會(huì)帶來(lái)一定的時(shí)間損耗梳猪。
簡(jiǎn)單來(lái)說(shuō)麻削,'jar' 模式更省空間,但是運(yùn)行時(shí)校驗(yàn)的耗時(shí)大約為 'raw' 模式的兩倍春弥。如果你沒(méi)有打開(kāi)運(yùn)行時(shí)校驗(yàn)呛哟,推薦使用 'jar' 模式。
八匿沛、如何兼容多渠道包扫责?
關(guān)于渠道包的問(wèn)題,若使用 flavor
編譯渠道包逃呼,會(huì)導(dǎo)致不同的渠道包由于 BuildConfig
變化導(dǎo)致 classes.dex
差異鳖孤。這里建議的方式有:
將渠道信息寫(xiě)在
AndroidManifest.xml
或文件中,例如channel.ini
抡笼;將渠道信息寫(xiě)在
apk
文件的zip comment
中苏揣,這種是建議方式,例如可以使用項(xiàng)目 packer-ng-plugin 或者可使用V2 Scheme
的 walle推姻;若不同渠道存在功能上的差異平匈,建議將差異部分放于單獨(dú)的 dex 或采用相同代碼不同配置方式實(shí)現(xiàn);
事實(shí)上,tinker
也支持多 flavor
直接編譯多個(gè)補(bǔ)丁包吐葱,具體可參考多 Flavor 打包街望。
九、tinker 是否兼容加固弟跑?
tinker 1.7.8 可以通過(guò) isProtectedApp
開(kāi)啟加固支持灾前,這種模式僅僅可以使用在加固應(yīng)用中。
加固廠商 | 測(cè)試 |
---|---|
騰訊云·樂(lè)固 | Tested |
愛(ài)加密 | Tested |
梆梆加固 | Tested |
360加固 | Tested孟辑,需要 5 月 8 日以后加固的版本 |
其他 | 請(qǐng)自行測(cè)試哎甲,只要滿足下面規(guī)則的都可以支持 |
這里是否支持加固,需要加固廠商明確以下兩點(diǎn):
不能提前導(dǎo)入類(lèi)饲嗽;
在
art
平臺(tái)若要編譯oat
文件炭玫,需要將內(nèi)聯(lián)取消。
十貌虾、Google Play 版本是否可以有 Tinker 相關(guān)代碼吞加?
由于 Google play 的使用者協(xié)議,對(duì)于 GP 渠道我們不能使用 Tinker 動(dòng)態(tài)更新代碼尽狠,這里會(huì)存在應(yīng)用被下架的風(fēng)險(xiǎn)衔憨。但是在 Google play 版本,我們依然可以存在 Tinker 的相關(guān)代碼袄膏,但是我們需要屏蔽補(bǔ)丁的網(wǎng)絡(luò)請(qǐng)求與合成相關(guān)操作践图。
十一、tinker 與 instant run 的兼容問(wèn)題沉馆?
事實(shí)上码党,若編譯時(shí)都使用 assemble*
,tinker
與 instant run
是可以兼容的斥黑。但是不少用戶基礎(chǔ)包與補(bǔ)丁包混用兩種模式導(dǎo)致補(bǔ)丁過(guò)大揖盘,所以 tinker
編譯時(shí)禁用 instant run
,我們可以在設(shè)置中禁用 instant run
或使用 assemble
方式編譯锌奴。
大家日常 debug
時(shí)若想開(kāi)啟 instant run
功能兽狭,可以將 tinker
暫時(shí)關(guān)閉:
ext {
//for some reason, you may want to ignore tinkerBuild, such as instant run debug build?
tinkerEnabled = false
}
十二、每次編譯我應(yīng)該保留哪些文件缨叫,如何兼容 AndResGuard椭符?
正如 sample 中 app/build.gradle荔燎,每個(gè)可能用到 Tinker 發(fā)布補(bǔ)丁的版本耻姥,需要在編譯后保存以下幾個(gè)文件:
編譯后生成的
apk
文件,即用來(lái)編譯補(bǔ)丁的基礎(chǔ)版本有咨;若使用
proguard
混淆琐簇,需要保持mapping.txt
文件;需要保留編譯時(shí)的
R.txt
文件;若你同時(shí)使用了資源混淆組件 AndResGuard婉商,你也需要將混淆資源的
resource_mapping.txt
保留下來(lái)似忧,同時(shí)將r/*
也添加到res pattern
中。具體我們可以參考 build.gradle丈秩。
微信通過(guò)將補(bǔ)丁編譯與 Jenkins 很好的結(jié)合起來(lái)盯捌,只需要點(diǎn)擊一個(gè)按鈕,即可方便的生成補(bǔ)丁包蘑秽。也可以參考 tinkerpatch-andresguard-sample饺著。
十三、tinkerId 應(yīng)該如何選擇肠牲?
tinkerId
是用來(lái)區(qū)分基準(zhǔn)安裝包的幼衰,我們需要嚴(yán)格保證一個(gè)基準(zhǔn)包的唯一性。在設(shè)計(jì)的初期缀雳,官方使用的是基準(zhǔn)包的 CentralDirectory
的 CRC
渡嚣,但某些 APP 為了生成渠道包會(huì)對(duì)安裝包重新打包,導(dǎo)致不同的渠道包的 CentralDirectory
并不一致肥印。
編譯補(bǔ)丁包時(shí)识椰,Tinker 會(huì)自動(dòng)讀取基準(zhǔn)包 AndroidManifest
的 tinkerId
作為 package_meta.txt
中的 TINKER_ID
。將本次編譯傳入的 tinkerId
竖独,作為 package_meta.txt
中的 NEW_TINKER_ID
裤唠。當(dāng)前 NEW_TINKER_ID
并沒(méi)有被使用到,只是保留作為配置項(xiàng)莹痢。如果我們使用 git rev
作為 tinkerid
种蘸,這時(shí)只要使用 git diff TINKER_ID NEW_TINKER_ID
即可獲得所有的代碼差異。
我們需要保證 tinkerId
一定是要唯一性的竞膳,這里推薦使用 git rev
或者 svn rev
航瞭。如果我們升級(jí)了客戶端版本,但 tinkerId
與舊版本相同坦辟,會(huì)導(dǎo)致可能會(huì)加載舊版本的補(bǔ)丁刊侯。這里我們一定要注意,升級(jí)可客戶端版本锉走,需要更新 tinkerId
滨彻!
十四、如何使生成的補(bǔ)丁包更信膊洹亭饵?
對(duì)于代碼來(lái)說(shuō),我們最好記住以下幾條規(guī)則:
編譯補(bǔ)丁包時(shí)梁厉,
proguard
使用applymapping
模式辜羊;對(duì)于多 dex 的情況,保持原本的分包規(guī)則,盡量減少由于分包變化而帶來(lái)的變更八秃。在生成補(bǔ)丁包過(guò)程中碱妆,對(duì)于 class 分包的變化將會(huì)輸出
Warning:Class Moved
日志,我們應(yīng)該盡量減少這種變化昔驱;大量靜態(tài)常量的改變與資源 R 文件的變更疹尾,這里推薦使用
applyResouceMapping
方式保持資源 ID。大量類(lèi)分包的改變對(duì)補(bǔ)丁包的影響不大骤肛,但是對(duì)于合成的時(shí)間消耗與占 ROM 的體積影響更大航棱。我們每次生成補(bǔ)丁后,都應(yīng)該查看TinkerPatch
輸出文件夾的日志萌衬;其他的例如使用
force jumbo
模式以及使用7zip
壓縮補(bǔ)丁包饮醇。
十五、關(guān)于使用的 ClassLoader 問(wèn)題秕豫?
Tinker 沒(méi)有使用 parent classloader
方案朴艰,而是使用 Multidex
插入 dexPathList
方式,這里主要考慮到分平臺(tái)內(nèi)部類(lèi)可能存在校驗(yàn) classloader
的問(wèn)題混移。
若
SDK >= 24
祠墅,即 Android N 版本,當(dāng)補(bǔ)丁存在時(shí)歌径,Tinker 將PathClassloader
替換為AndroidNClassLoader
毁嗦,但是它依然繼承與PathClassLoader
。我們依然可以像以往那樣對(duì)它進(jìn)行類(lèi)似makeDexElements
的操作回铛。狗准;若
SDK < 14
,Tinker 沒(méi)有對(duì)classloader
做處理茵肃,這里需要注意補(bǔ)丁的Dex
是插入在dexElement
的前方腔长。
十六、什么時(shí)候調(diào)用 installTinker验残?
首先我們推薦在最開(kāi)始的時(shí)候就是執(zhí)行 installTinker
操作捞附,但是即使你不去 installTinker
,也不會(huì)影響 Tinker
對(duì)代碼您没、So 與資源的加載鸟召。installTinker
只是做了以下幾件事件:
回調(diào)
LoadReporter
,返回加載結(jié)果氨鹏;初始化各個(gè)自定義類(lèi)與 Tinker 實(shí)例欧募,可以調(diào)用 Tinker 相關(guān) API,發(fā)起升級(jí)補(bǔ)丁以及處理相關(guān)的回調(diào)喻犁。
事實(shí)上槽片,微信只在主進(jìn)程與 :patch
進(jìn)程執(zhí)行 installTinker
操作。其他進(jìn)程只要不處理回調(diào)結(jié)果肢础,不發(fā)起補(bǔ)丁請(qǐng)求即可还栓。在 SampleUncaughtExceptionHandler 中,為了防止 Crash
并沒(méi)有執(zhí)行 installTinker
传轰,全部使用的是 TinkerApplicationHelper 中的 API剩盒,詳細(xì)可以查看 Tinker API 概覽。
十七慨蛙、Proguard 5.2.1 applymapping 出現(xiàn) Warning辽聊?
這是因?yàn)?5.2.1 增加了內(nèi)聯(lián)函數(shù)的行輸出信息導(dǎo)致,你可以使用以下幾種方法解決:
使用 5.1 版本
proguard
期贫;將內(nèi)聯(lián)函數(shù)的優(yōu)化關(guān)掉跟匆;
自己對(duì)
mapping
文件去除內(nèi)聯(lián)函數(shù)的行信息。
如果使用 4.X 版本的 Proguard
強(qiáng)烈建議升級(jí)到 5.1 版本通砍÷瓯郏可以先下載 5.1 的 Proguard
, 然后通過(guò)以下方式指定:
classpath files('proguard-5.1.jar')
若使用 gradle 編譯封孙,與 multiDexKeepProguard
不同迹冤,我們無(wú)需將生成的 tinker_proguard.pro
拷貝到自己的配置中。另外一個(gè)方面虎忌,若 applymapping
過(guò)程出現(xiàn)沖突泡徙,我們可以采取以下幾個(gè)方法:
添加
ignoreWarning
;需要注意的是如果某些類(lèi)的確需要采用新的mapping
膜蠢,這樣補(bǔ)丁后 App 會(huì)出問(wèn)題堪藐,一般并不建議采用這種方式;修改基準(zhǔn)包的
mapping
文件挑围;我們需要根據(jù)新的mapping
文件庶橱,修正基準(zhǔn)包的mapping
文件。例如將warning
項(xiàng)刪掉或者將新mapping
中keep
的項(xiàng)復(fù)寫(xiě)到基準(zhǔn)的mapping
中贪惹∷照拢可以參考腳本 proguard_warning.py 與 merge_mapping.py。
注意奏瞬,如果想通過(guò)直接刪除舊 mapping
文件的沖突項(xiàng)枫绅,需要注意刪除類(lèi)的內(nèi)部類(lèi)是否存在混淆沖突。
十八硼端、TinkerPatch 補(bǔ)丁管理后臺(tái)與 Tinker 的關(guān)系并淋?
TinkerPatch 平臺(tái)是第三方開(kāi)發(fā)基于 CDN 分發(fā)的補(bǔ)丁管理后臺(tái)。它提供了補(bǔ)丁后臺(tái)托管珍昨,版本管理县耽,一鍵傻瓜式接入等功能句喷,讓我們可以無(wú)需修改任何代碼即可輕松接入Tinker。
我們可以根據(jù)自己的需要選擇接入兔毙,它是獨(dú)立于 Tinker 項(xiàng)目之外唾琼。
十九、Tinker 的最佳實(shí)踐澎剥?
為了使補(bǔ)丁的成功率更高锡溯,官方在 Sample 中還做了以下工作:
由于合成進(jìn)程可能被各種原因殺死,使用 UpgradePatchRetry.java 來(lái)做重試功能哑姚,提高成功率祭饭;
防止補(bǔ)丁后程序無(wú)法啟動(dòng),使用 SampleUncaughtExceptionHandler.java 做
crash
啟動(dòng)保護(hù)叙量。這里更推薦的是進(jìn)入安全模式倡蝙,使用配置的方式強(qiáng)制清理或者升級(jí)補(bǔ)丁绞佩;為了防止
BuildConfig
的改變導(dǎo)致大量類(lèi)的變更悠咱,使用 BuildInfo.java 非 final 的變量來(lái)中轉(zhuǎn)。為了加快補(bǔ)丁應(yīng)用同時(shí)保持用戶體驗(yàn)征炼,SampleResultService.java 在應(yīng)用退入后臺(tái)或手機(jī)滅屏?xí)r析既,才殺掉進(jìn)程。你也可以在殺掉進(jìn)程前谆奥,直接通過(guò)發(fā)送 broadcast 或 service intent 的方式盡快的重啟進(jìn)程眼坏。
把
jumboMode
打開(kāi),防止由于字符串增多導(dǎo)致force-jumbol
酸些,導(dǎo)致更多的變更宰译。使用
zip comment
方式生成渠道包。