微信熱修復(fù) Tinker 快速上手

前言

希望通過(guò)本文能夠幫助之前沒(méi)有接觸過(guò) Tinker 的同學(xué)邢笙,快速了解利用 Tinker 生成及使用補(bǔ)丁包的過(guò)程。

Tinker 版本:1.8.1
Tinker 官方文檔:https://github.com/Tencent/tinker/wiki

gradle 接入

我沒(méi)有 clone 官方的例子,也沒(méi)有在現(xiàn)有項(xiàng)目上直接接入,而是創(chuàng)建了一個(gè)新的項(xiàng)目。

在項(xiàng)目的 build.gradle 中憨愉,添加tinker-patch-gradle-plugin依賴:

buildscript {
    dependencies {
        classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.8.1')
    }
}

然后在 app 的 gradle 文件 app/build.gradle,添加 tinker 的庫(kù)依賴以及 apply tinker 的 gradle 插件:

dependencies {
    provided('com.tencent.tinker:tinker-android-anno:1.8.1')
    compile('com.tencent.tinker:tinker-android-lib:1.8.1') 
}
...
apply plugin: 'com.tencent.tinker.patch'

在這一步不用著急編譯卿捎,下面還有 gradle 的詳細(xì)配置配紫。

生成 Application

tinker 建議編寫(xiě)一個(gè) DefaultApplicationLike 的子類,并使用@DefaultLifeCycle注解生成 Application.

@DefaultLifeCycle(application = ".MyApplication", //要生成的application名稱
                  flags = ShareConstants.TINKER_ENABLE_ALL)
public class MyApplicationLike extends DefaultApplicationLike {

    public MyApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag, 
                             long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, 
              applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
    }

    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        TinkerInstaller.install(this);
    }
}

注意 application 名稱為.MyApplication午阵,我創(chuàng)建的 MyApplicationLike 所在的包為tech.gujin.tinkersample.application躺孝,生成的 MyApplication 也在這個(gè)包下〉坠穑或者將包名寫(xiě)全:application = "tech.gujin.tinkersample.application.MyApplication"植袍,生成的文件都是一樣的。

之后注冊(cè) Application 到 AndroidManifest 中:

<application
    android:name="tech.gujin.tinkersample.application.MyApplication"
    ...
</application>

如果報(bào)錯(cuò)現(xiàn)在不用處理籽懦,編譯后會(huì)自動(dòng)生成的于个。

gradle 配置

我直接拷貝了官方例子,修改了其中獲取 tinkerId 的方法暮顺,bakPath 的路徑厅篓,移除了多渠道部分。

def bakPath = file("./tinker-old/") //可自行定義文件路徑

ext {
    tinkerId = "tinker_id_" + android.defaultConfig.versionName + "_" + android.defaultConfig.versionCode
    tinkerEnabled = true
    tinkerOldApkPath = "${bakPath}/app-release-1.0-1.apk" //可自行修改文件名
    tinkerApplyMappingPath = "${bakPath}/app-release-1.0-1-mapping.txt"
    tinkerApplyResourcePath = "${bakPath}/app-release-1.0-1-R.txt"
}

因?yàn)橐裳a(bǔ)丁捶码,tinker 需要上一個(gè)版本的安裝包用來(lái)比較差異羽氮。
我創(chuàng)建了tinker-old文件夾,放入上一個(gè)版本名為app-release-1.0-1.apk的安裝包惫恼,并將路徑設(shè)置給 tinkerOldApkPath.
為了減少補(bǔ)丁包的大小档押,還可以繼續(xù)設(shè)置 tinkerApplyMappingPath 和 tinkerApplyResourcePath.
其余地方并無(wú)太大變化,更多可以看修改后的gradle祈纯。
首次接入沒(méi)有舊的安裝包也不用擔(dān)心令宿,如果指定文件不存在 tinker 會(huì)自動(dòng)忽略。

使用前的準(zhǔn)備

創(chuàng)建一個(gè)很簡(jiǎn)單的 Activity:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((TextView) findViewById(R.id.tv_msg)).setText("此版本存在BUG");

        File file = new File(getExternalCacheDir(), "/patch_signed_7zip.apk");
        if (file.exists()) {
            TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), file.getAbsolutePath());
        }
    }
}

這里省去了訪問(wèn)服務(wù)器判斷有沒(méi)有補(bǔ)丁包和下載的邏輯盆繁,簡(jiǎn)化為如果/storage/emulated/0/Android/data/tech.gujin.tinkersample/cache目錄下有patch_signed_7zip.apk補(bǔ)丁包就進(jìn)行更新掀淘。

然后編譯一個(gè) release 包旬蟋,安裝到手機(jī)上:

這是一個(gè)存在Bug的版本

制作補(bǔ)丁包

修改 TextView 的文字油昂,然后升級(jí)下 versionCode 和 versionName,就當(dāng)是 1.1 版本修復(fù)了 1.0 版本的 Bug.
剛才的打包過(guò)程會(huì)自動(dòng)將 apk,mapping 和 R 文件復(fù)制到tinker-old文件夾中冕碟,根據(jù)文件名配置下 tinkerOldApkPath拦惋、tinkerApplyMappingPath 和 tinkerApplyResourcePath.

然后在 Terminal 輸入 gradlew tinkerPatchRelease,或者在 Gradle projects 中找到相應(yīng)的 project 運(yùn)行即可安寺。

tinkerPatchRelease

等運(yùn)行結(jié)束后厕妖,補(bǔ)丁包生成在/build/outputs/tinkerPatch目錄下,使用patch_signed_7zip.apk挑庶,它是簽名后并使用 7zip 壓縮的補(bǔ)丁包言秸。

到此為止,補(bǔ)丁包就制作好了迎捺。

使用補(bǔ)丁

本例中簡(jiǎn)化了流程举畸,我直接將補(bǔ)丁放到 /storage/emulated/0/Android/data/tech.gujin.tinkersample/cache目錄。
殺死進(jìn)程重新打開(kāi)應(yīng)用凳枝,可以看到打印出 log:

I/Tinker.DefaultTinkerResultService: DefaultTinkerResultService received a result:
                                     PatchResult:
                                     isSuccess:true
                                     rawPatchFilePath:/storage/emulated/0/Android/data/tech.gujin.tinkersample/cache/patch_signed_7zip.apk
                                     costTime:530
                                     patchVersion:a5c8417e691fd9cffe83c11cd0d37eff

然后應(yīng)用直接退出了抄沮,這是因?yàn)?tinker 提供的 DefaultTinkerResultService 中,補(bǔ)丁升級(jí)成功后會(huì)殺死當(dāng)前進(jìn)程岖瑰,可以繼承 DefaultTinkerResultService 實(shí)現(xiàn)自己的回調(diào)叛买。

再次打開(kāi)應(yīng)用可以看到補(bǔ)丁已經(jīng)生效了:

已修復(fù)Bug

至此,tinker 生成及更新補(bǔ)丁包的過(guò)程就已經(jīng)介紹完畢了蹋订。
代碼已托管至 Github:GuJin/TinkerSample
謝謝大家率挣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市露戒,隨后出現(xiàn)的幾起案子难礼,更是在濱河造成了極大的恐慌,老刑警劉巖玫锋,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛾茉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡撩鹿,警方通過(guò)查閱死者的電腦和手機(jī)谦炬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)节沦,“玉大人键思,你說(shuō)我怎么就攤上這事「幔” “怎么了吼鳞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)叫搁。 經(jīng)常有香客問(wèn)我赔桌,道長(zhǎng)供炎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任疾党,我火速辦了婚禮音诫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雪位。我一直安慰自己竭钝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布雹洗。 她就那樣靜靜地躺著香罐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪时肿。 梳的紋絲不亂的頭發(fā)上穴吹,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音嗜侮,去河邊找鬼港令。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锈颗,可吹牛的內(nèi)容都是我干的顷霹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼击吱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼淋淀!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起覆醇,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤朵纷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后永脓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體袍辞,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年常摧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搅吁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡落午,死狀恐怖谎懦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溃斋,我是刑警寧澤界拦,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站梗劫,受9級(jí)特大地震影響享甸,放射性物質(zhì)發(fā)生泄漏截碴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一枪萄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猫妙,春花似錦瓷翻、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至彼哼,卻和暖如春对妄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敢朱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工剪菱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拴签。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓孝常,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蚓哩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子构灸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容