上月領(lǐng)導(dǎo)有想法雇毫,希望公司能實(shí)現(xiàn)熱更新的技術(shù)與提供解決方案瓦糕,應(yīng)對(duì)一些函數(shù),變量轰绵,配置級(jí)別的bug的修復(fù)莹桅。特去整理了下昌执,整理了三個(gè)可探究的方案:andfix Dexposed ClassLoader。
現(xiàn)在整理下優(yōu)缺點(diǎn):
Dexposed:支持的系統(tǒng)版本统翩,上限是4.4仙蚜,直接pass,采用的AOP切片式思維厂汗,在數(shù)據(jù)統(tǒng)計(jì)這塊有大用途委粉,阿里開(kāi)源的庫(kù),比較老的一個(gè)庫(kù)娶桦;
ClassLoader: 插件式思維贾节,和注入式更新還是有點(diǎn)不一樣;
andfix:支持的系統(tǒng)全面衷畦,阿里2015年開(kāi)源的庫(kù)栗涂,在native層注入代碼,解決思路有點(diǎn)類似IOS的jspatch祈争。
最終決定斤程,采用andfix的解決方案,馬上教程式的給出集成方案菩混。
一忿墅、基礎(chǔ)原理
全稱Android hot-fix,是alibaba的Android熱修復(fù)框架沮峡,支持Android 2.3到6.0的版本疚脐,支持arm與X86系統(tǒng)架構(gòu),支持Dalvik和ART Runtime邢疙。
原理
AndFix的原理就是方法的替換棍弄,把有bug的方法替換成補(bǔ)丁文件中的方法。
原理-替換方法
二疟游、使用教程
1)github上的鏈接
https://github.com/alibaba/AndFix
作為module集成到項(xiàng)目中
2)在AndroidMainFest.xml中生命所需要的權(quán)限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
3) 添加依賴和混淆
dependencies { compile 'com.alipay.euler:andfix:0.4.0@aar' }
-keep class * extends java.lang.annotation.Annotation
-keepclasseswithmembernames class * {
native <methods>;
}
4)在Application.onCreate()中初始化PatchManager
public class HotPatchApplication extends Application {
public static PatchManager mPatchManager;
@Override
public void onCreate() {
super.onCreate();
// 初始化patch管理類
mPatchManager = new PatchManager(this);
// 初始化patch版本
mPatchManager.init("1.0");
// 加載已經(jīng)添加到PatchManager中的patch
mPatchManager.loadPatch();
}
}
5)找個(gè)地方加載補(bǔ)丁呼畸,我們這里為了演示,點(diǎn)擊按鈕進(jìn)行加載補(bǔ)丁
findViewById(R.id.main_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
update();
}
});
private void update() {
String patchFileStr = Environment.getExternalStorageDirectory().getAbsolutePath() + APATCH_PATH;
try {
HotPatchApplication.mPatchManager.addPatch(patchFileStr);
} catch (IOException e) {
e.printStackTrace();
}
}
PatchManager的addPatch方法加載新補(bǔ)丁颁虐,項(xiàng)目中可以在下載補(bǔ)丁文件之后調(diào)用,這里為了演示就把補(bǔ)丁文件放在本地的SD卡中了役耕,代碼中patchFileStr就是補(bǔ)丁存放的位置,.apatch就是生成補(bǔ)丁文件的后綴名聪廉,fix就是補(bǔ)丁文件的名字瞬痘,這里我們將其名字寫(xiě)死。
至此板熊,熱更新的功能代碼全部寫(xiě)完
6)寫(xiě)上測(cè)試是否替代成功的代碼
熱更新覆蓋前的代碼如下:
mainTv = (TextView) findViewById(R.id.main_tv);mainTv.setText("點(diǎn)擊Toast");
mainTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showToast();
}
});
private void showToast() {
Toast.makeText(this, "打補(bǔ)丁之前", Toast.LENGTH_LONG).show();
}
編譯打包城一個(gè)old.apk(使用release的簽名證書(shū))
熱更新覆蓋的代碼如下:
mainTv = (TextView) findViewById(R.id.main_tv);
mainTv.setText("點(diǎn)擊Toast");
mainTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showToast();
}
});
private void showToast() {
Toast.makeText(this, "打補(bǔ)丁之后", Toast.LENGTH_LONG).show();
}
編譯打包成一個(gè)new.apk(使用release的簽名證書(shū))框全。
三、測(cè)試過(guò)程
使用andfix中的diff工具執(zhí)行干签,生成一個(gè)appatch文件津辩,命名為fix.appacth
adb push上述fix.appatch文件到sd卡中;
3)
安裝old.apk
4)打開(kāi)app容劳,點(diǎn)擊跟新喘沿,
點(diǎn)擊更新按鈕,然后點(diǎn)擊toast按鈕竭贩,應(yīng)當(dāng)能看到 “打補(bǔ)丁之后”的提示蚜印。