介紹熱修復(fù)之前,我們先看下InstantRun
InstantRun
不得不說InstantRun真是個(gè)好東西。目前主流的熱修復(fù)框架都有或多或少的參考InstantRun的某些技術(shù)點(diǎn)榛了。
我們知道,InstantRun對(duì)應(yīng)三種更新機(jī)制:
冷插拔:我們稱之為重啟更新機(jī)制
溫插拔:我們稱之為重啟Activity更新機(jī)制沟蔑,在重啟的時(shí)候替換Application的classLoader來加載dex
熱插拔:我們稱之為熱更新機(jī)制是新建classLoader來加載dex
Robus求类,其熱修復(fù)的關(guān)鍵技術(shù)點(diǎn)就是采用了InstantRun中的熱更新機(jī)制,對(duì)應(yīng)于多ClassLoader的動(dòng)態(tài)加載方案叠穆,即一個(gè)dex文件對(duì)應(yīng)一個(gè)新建ClassLoader
優(yōu)勢(shì)
支持Android2.3-7.x版本
高兼容性少漆,高穩(wěn)定性,修復(fù)成功率高達(dá)三個(gè)九
補(bǔ)丁下發(fā)立即生效硼被,不需要重新啟動(dòng)
支持方法級(jí)別的修復(fù)示损,包括靜態(tài)方法
支持增加方法和類
支持ProGuard的混淆、內(nèi)聯(lián)嚷硫、優(yōu)化等操作
流程
我們先看集成流程圖?
美團(tuán)熱修復(fù)官方地址:Robust
集成
把項(xiàng)目下載到本地并解壓
在整個(gè)項(xiàng)目的build.gradle加入classpath
classpath 'com.meituan.robust:gradle-plugin:0.4.72'
classpath 'com.meituan.robust:auto-patch-plugin:0.4.72'
在App的build.gradle检访,加入如下依賴
compile 'com.meituan.robust:robust:0.4.72'
同時(shí)添加:
//apply plugin: 'auto-patch-plugin'
apply plugin: 'robust'
項(xiàng)目發(fā)release版本,把簽名文件在gradle中寫好
開啟proguard混淆開關(guān)始鱼,robust做了混淆文件和代碼的映射
將robust項(xiàng)目源碼中的app/src/robust.xml拷貝到自己項(xiàng)目下的app/src路徑下
打開robust.xml,將要修改的包名換成自己的包名
執(zhí)行g(shù)radle命令
./gradlew clean? assembleRelease --stacktrace --no-daemon
在app下新建robust目錄脆贵,并將app/build/outputs文件夾下會(huì)生成mapping.txt,methodsMap.robust文件医清,將他們拷貝到app/robust文件夾中保存
?methodMap.robust,該文件在打補(bǔ)丁的時(shí)候用來區(qū)別到底哪些方法需要被修復(fù)卖氨,所以有它才能打補(bǔ)丁会烙。而上文所說的還有mapping.txt文件,該文件列出了原始的類筒捺,方法和字段名與混淆后代碼間的映射持搜。
修改
先看下熱修復(fù)之前的情況
?功能很簡(jiǎn)單,第二個(gè)按鈕跳轉(zhuǎn)到第二個(gè)Activity焙矛。第一個(gè)按鈕加載一會(huì)兒生成的patch文件葫盼。跳轉(zhuǎn)代碼如下
findViewById(R.id.btn_load_patch).setOnClickListener(view->
? ? ? ? ? ? ? ? new PatchExecutor(this,new PatchManipulateImp(),new RobustCallBackSample()).start());
findViewById(R.id.btn_start_second).setOnClickListener(view->startActivity(new Intent(this, SecondActivity.class)));
其中,PatchManipulateImp和RobustCallBackSample都是從解壓文件拷貝過來的村斟。?
這里一定要注意:
PatchesInfoImpl類中的setPatchesInfoImplClassFullName包名要和robust.xml中節(jié)點(diǎn)下的包名對(duì)應(yīng)
patch.setPatchesInfoImplClassFullName("com.example.robustsample.PatchesInfoImpl");
修改第二個(gè)Activity中代碼
修改前
修改后
生成Patch文件
在app的build.gradle中贫导,注釋掉robust插件,打開auto-patch-plugin插件
再一次執(zhí)行打包命令
gradlew clean? assembleRelease --stacktrace --no-daemon
看到build false蟆盹,但是patch已經(jīng)成功孩灯,patch文件的路徑為:
在sd卡下新建robust文件夾,用于存放patch補(bǔ)丁文件
執(zhí)行push命令逾滥,將本地patch放入手機(jī)新建的robust文件夾內(nèi)
adb push app/build/outputs/robust/patch.jar /sdcard/robust
?當(dāng)然也可以拖動(dòng)到Download峰档,再移動(dòng)到指定目錄下
結(jié)果
最后一步,點(diǎn)擊第一個(gè)按鈕寨昙,再點(diǎn)擊跳轉(zhuǎn)到第二個(gè)按鈕讥巡。先看效果,顯示的內(nèi)容會(huì)發(fā)生變化
其中點(diǎn)擊加載patch文件時(shí)舔哪,返回true欢顷,表示已修復(fù)成功?
參考: