什么是熱修復(fù)祖今?
熱修復(fù)提出于2014年歧斟,興起于2016年紧武,尤其是在Instant run 問世以后击你,各種熱修復(fù)技術(shù)相繼涌出玉组。
是一種擺脫傳統(tǒng)發(fā)版方案直接使用補(bǔ)丁來更新app內(nèi)容谎柄,不需要重新下載安裝apk等略過一系列繁瑣過程的新興技術(shù),目前國內(nèi)部分成熟App都擁有自己的熱修復(fù)技術(shù)惯雳,如:手淘朝巫、QQ、微信石景、美團(tuán)劈猿、餓了么等。
熱修復(fù)有什么優(yōu)勢&為什么要使用熱修復(fù)潮孽?
來看一個場景:公司一個項(xiàng)目A在上線后發(fā)現(xiàn)一個嚴(yán)重bug如果不緊急修復(fù)可能導(dǎo)致用戶流失糙臼,這種情況下如果是傳統(tǒng)的app更新就很麻煩了大概是這個流程:
這期間重新發(fā)版涉及到提交測試環(huán)節(jié),這樣修復(fù)一個bug很不及時(shí)恩商,如果使用熱修復(fù)方案变逃,它將變得很簡單:
其優(yōu)勢為:
- 無需重新發(fā)版,簡單高效
- 用戶無感知怠堪,無需下載新應(yīng)用揽乱,代價(jià)小
- 修復(fù)成功率高,挽回用戶群體
熱修復(fù)是如何工作的粟矿?
- 2017年6月手淘聯(lián)合阿里云正式發(fā)布了新一代非侵入式Android熱修復(fù)方案 - Sophix
它能修復(fù):代碼凰棉、資源、SO庫陌粹,下圖為Sophix與微信和餓了么熱修復(fù)技術(shù)對比表
從表中我們能知道個大概撒犀,就是Sophix似乎更值得使用一下。
分別介紹QQ空間超級不定掏秩、微信Tinker和Sophix的前身HotFix各自的工作原理或舞。
首先了解一下apk的執(zhí)行過程:代碼被編譯Build后生成apk文件,其實(shí)在里面生成了一個classes.dex文件蒙幻。
我們解壓一個apk文件如下圖:
這個classes.dex就是所有代碼的集合映凳,是一個可執(zhí)行文件,android運(yùn)行apk實(shí)質(zhì)是解壓apk運(yùn)行里面的這個的dex文件邮破。
apk首次運(yùn)行的時(shí)候會對這個dex文件進(jìn)行優(yōu)化诈豌,優(yōu)化后生成一個odex文件,存在于緩存中抒和,下次再啟動就直接打開這個odex文件矫渔,達(dá)到快速打開目的。而執(zhí)行apk的過程就是遍歷這個dex并作出相應(yīng)操作的過程摧莽,遍歷后的dex方法存放在一個Elements數(shù)組中庙洼,它的長度限制是65536.即日常說的65K.
如果我們apk因?yàn)樘嫶蠡蛘呤且萌綆焯鄬?dǎo)致方法數(shù)超過65K,就會報(bào)錯.
而谷歌已經(jīng)在Android 5.0開始支持Multdex.
在知道上面信息后,我們談?wù)勥@三家的熱修復(fù)是如何實(shí)現(xiàn)的
1.QQ空間超級補(bǔ)丁:基于DEX分包方案送膳,使用了多DEX加載的原理员魏,大致的過程就是:把BUG方法修復(fù)以后,放到一個單獨(dú)的DEX里叠聋,插入到dexElements數(shù)組的最前面撕阎,讓虛擬機(jī)去加載修復(fù)完后的方法。
當(dāng)patch.dex中包含Test.class時(shí)就會優(yōu)先加載碌补,在后續(xù)的DEX中遇到Test.class的話就會直接返回而不去加載虏束,這樣就達(dá)到了修復(fù)的目的.
2.微信Tinker:微信針對QQ空間超級補(bǔ)丁技術(shù)的不足提出了一個提供DEX差量包,整體替換DEX的方案厦章。主要的原理是與QQ空間超級補(bǔ)丁技術(shù)基本相同镇匀,區(qū)別在于不再將patch.dex增加到elements數(shù)組中,而是差量的方式給出patch.dex袜啃,然后將patch.dex與應(yīng)用的classes.dex合并汗侵,然后整體替換掉舊的DEX文件,以達(dá)到修復(fù)的目的群发。
3.AndFix:不同于QQ空間超級補(bǔ)丁技術(shù)和微信Tinker通過增加或替換整個DEX的方案晰韵,提供了一種運(yùn)行時(shí)在Native修改Filed指針的方式,實(shí)現(xiàn)方法的替換熟妓,達(dá)到即時(shí)生效無需重啟雪猪,對應(yīng)用無性能消耗的目的。
AndFix與HotFix的關(guān)系如下:
AndFix實(shí)現(xiàn)原理:
AndFix實(shí)現(xiàn)過程:
更詳細(xì)的說明戳這里:三大流派之簡單對比
阿里云Sophix熱修復(fù)之簡單使用
Sophix集成示例:
第一步:找到Project的build.gradle文件起愈,在allProjects節(jié)點(diǎn)下加上如下代碼:
repositories {
maven { url"http://maven.aliyun.com/nexus/content/repositories/releases"}
}
第二步:找到Module的build.gradle文件只恨,添加依賴:
compile'com.aliyun.ams:alicloud-android-hotfix:3.0.7'
然后同步project
第三步:添加權(quán)限,SDK使用到以下權(quán)限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--<! -- 外部存儲讀權(quán)限,調(diào)試工具加載本地補(bǔ)丁需要 –>-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
READ_EXTERNAL_STORAGE/ACCESS_WIFI_STATE 權(quán)限屬于Dangerous Permissions,自行做好android6.0以上的運(yùn)行時(shí)權(quán)限獲取
第四步:密鑰等配置抬虽,在application節(jié)點(diǎn)下加入以下配置:
<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="App ID" />
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="App Secret" />
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="RSA密鑰" />
第五步:登錄阿里云熱修復(fù)管理控制臺官觅,填入對應(yīng)3個value
第六步:代碼集成
在Application的attachBaseContext方法里加入Sophix初始化
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
SophixManager.getInstance().setContext(this)
.setAppVersion(getAppVersion())
.setAesKey(null)
.setEnableDebug(true)
.setPatchLoadStatusStub(new PatchLoadStatusListener() {
@Override
public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
// 補(bǔ)丁加載回調(diào)通知
if (code == PatchStatus.CODE_LOAD_SUCCESS) {
// 表明補(bǔ)丁加載成功
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 表明新補(bǔ)丁生效需要重啟. 開發(fā)者可提示用戶或者強(qiáng)制重啟;
// 建議: 用戶可以監(jiān)聽進(jìn)入后臺事件, 然后應(yīng)用自殺
} else if (code == PatchStatus.CODE_LOAD_FAIL) {
// 內(nèi)部引擎異常, 推薦此時(shí)清空本地補(bǔ)丁, 防止失敗補(bǔ)丁重復(fù)加載
SophixManager.getInstance().cleanPatches();
} else {
// 其它錯誤信息, 查看PatchStatus類說明
}
}
}).initialize();
}
@Override
public void onCreate() {
super.onCreate();
......
// queryAndLoadNewPatch不可放在attachBaseContext 中,否則無網(wǎng)絡(luò)權(quán)限斥赋,建議放在后面任意時(shí)刻缰猴,如onCreate中
SophixManager.getInstance().queryAndLoadNewPatch();
}
自此SDK的集成已經(jīng)差不多完成,官方給出了很詳細(xì)的集成方法疤剑,官方集成文檔
第七步:生成熱修復(fù)補(bǔ)丁
我們直接看官方文檔這里面寫的很詳細(xì),細(xì)到每個設(shè)置每個參數(shù)都有說明
第八步:調(diào)試并發(fā)布補(bǔ)丁
首先我們需要上傳補(bǔ)丁到阿里云管理后臺闷堡,點(diǎn)此查看詳細(xì)操作
接下來是對補(bǔ)丁的調(diào)試隘膘,點(diǎn)此查看詳細(xì)操作
調(diào)試沒毛病后,發(fā)布補(bǔ)丁杠览,參考管理后臺使用說明的step5
查看我自己的Demo數(shù)據(jù)