天天看點

# 阿裡熱更新方案

1.什麼叫熱更新

熱更新是一種各大手遊等衆多App常用的更新方式。簡單來說,就是在使用者通過App Store下載下傳App之後,打開App時遇到的即時更新。

2.為什麼要做熱更新

當一個App釋出之後,突然發現了一個嚴重bug需要進行緊急修複,這時候公司各方就會忙得焦頭爛額:重新打包App、測試、向各個應用市場和管道換包、提示使用者更新、使用者下載下傳、覆寫安裝。

重點是還會有原來的版本遺留,無論你怎麼提示都有人放棄治療,不願意更新,強制不能使用體驗又足夠糟糕到讓人不能啟齒。

如果這是一個影響公司收入或者體驗影響極其不好的Bug,那完蛋了,可能公司老闆會對整個技術團隊的技術能力喪失信心,其對技術人員的傷害是緻命的。

熱更新的方案

技術派系:

• Native,代表有阿裡的Dexposed、AndFix與騰訊的内部方案KKFix;

• Java,代表有Qzone的超級更新檔、大衆點評的nuwa、百度金融的rocooFix, 餓了麼的amigo以及美團的robust。

Native流派與Java流派都有着自己的優缺點,它們具體差異大家可參考上文。事實上從來都沒有最好的方案,隻有最适合自己的。

ClassLoader

我們知道Java在運作時加載對應的類是通過ClassLoader來實作的,ClassLoader本身是一個抽象類,Android中使用PathClassLoader類作為Android的預設的類加載器,

PathClassLoader其實實作的就是簡單的從檔案系統中加載類檔案。PathClassLoade本身繼承自BaseDexClassLoader,BaseDexClassLoader重寫了findClass方法,

該方法是ClassLoader的核心

@Override

protected Class

實作

上面分析了Android中的類的加載的流程,可以看出來DexPathList對象中的dexElements清單是類加載的一個核心,一個類如果能被成功加載,那麼它的dex一定

會出現在dexElements所對應的dex檔案中,并且dexElements中出現的順序也很重要,在dexElements前面出現的dex會被優先加載,一旦Class被加載成功,

就會立即傳回,也就是說,我們的如果想做hotpatch,一定要保證我們的hotpacth dex檔案出現在dexElements清單的前面。

要實作熱更新,就需要我們在運作時去更改PathClassLoader.pathList.dexElements,由于這些屬性都是private的,是以需要通過反射來修改。另外,構造我們自己的dex檔案

所對應的dexElements數組的時候,我們也可以采取一個比較取巧的方式,就是通過構造一個DexClassLoader對象來加載我們的dex檔案,并且調用一次dexClassLoader.loadClass(dummyClassName);

方法,這樣,dexClassLoader.pathList.dexElements中,就會包含我們的dex,通過把dexClassLoader.pathList.dexElements插入到系統預設的classLoader.pathList.dexElements清單前面,就可以讓系統優先加載我們的dex中的類,進而可以實作熱更新了。

說了那麼多,下面我們就以阿裡百川HotFix熱更新內建加使用

首先建立開發者賬号,并建立一個應用如下:參數填入到對應的位置在清單檔案中

# 阿裡熱更新方案

1.Androidstutio內建:

首先還是按照阿裡文檔內建,有可能不成功的(文檔上面說了注意: 1.4.0版本的倉庫位址已經發生了變更, 請更新到上述百川最新的倉庫位址),反正我是沒有成功

我的(這是根據阿裡給的dome裡面配置的):

2.先在project的gradle裡面添加:

allprojects {

repositories {

jcenter()

maven {

//百川倉庫, ut/utdid

url “http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories”

}

}

}

然後在module的gradle中添加:

dependencies {

compile ‘com.taobao.android:alisdk-hotfix:1.4.0’

}

3.建立一個Application

public class Myapplication extends Application {

@Override

public void onCreate() {

super.onCreate();

HotFixManager.getInstance().setContext(this)

.setAppVersion(“你的版本号”)

.setAppId(“你在開發者平台建立應用的appId”)

.setAesKey(null)//如果對更新檔進行了Aes加密,這裡就要填上,具體見開發文檔

.setSupportHotpatch(true)

.setEnableDebug(true)

.setPatchLoadStatusStub(new PatchLoadStatusListener() {

@Override

public void onload(final int mode, final int code, final String info, final int handlePatchVersion) {

// 更新檔加載回調通知

if (code == PatchStatusCode.CODE_SUCCESS_LOAD) {

// TODO: 10/24/16 表明更新檔加載成功

} else if (code == PatchStatusCode.CODE_ERROR_NEEDRESTART) {

// TODO: 10/24/16 表明新更新檔生效需要重新開機. 業務方可自行實作邏輯, 提示使用者或者強制重新開機, 建議: 使用者可以監聽進入背景事件, 然後應用自殺

} else if (code == PatchStatusCode.CODE_ERROR_INNERENGINEFAIL) {

// 内部引擎加載異常, 推薦此時清空本地更新檔, 但是不清空本地版本号, 防止失敗更新檔重複加載

//HotFixManager.getInstance().cleanPatches(false);

} else {

// TODO: 10/25/16 其它錯誤資訊, 檢視PatchStatusCode類說明

}

}

}).initialize();

}

}

4.添加網絡權限

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” />

uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>

在清單檔案中添加key

至此我們的內建過程就已經完成了,下面進入調試使用階段

首先我們要建立一個old.apk(也就是有問題的apk)

首先将Myapplication中的.setAppVersion(“1.0”)//設定一個版本号,随便設定,後面再上傳更新檔的時候會将更新檔的版本号改成這個,這兩個地方的版本哈要一緻

接下來我們釋出一個有問題的apk或是說old.apk,并将這個old.apk放到一個單獨的地方(我的:C:\Users\Laer\Desktop\oldApk\old.apk),以免釋出新版本的時候覆寫這個舊版本(這個old.apk會在生成更新檔時用到)

然後更改想要修改的代碼,直接釋出生成一個new.apk,同理将這個新的apk放到一個特定的位置(我的: C:\Users\Laer\Desktop\newApk\new.apk)

接下來我們就要使用阿裡提供的生成更新檔的工具了:

http://ams-hotfix-repo.oss-cn-shanghai.aliyuncs.com/SophixPatchTool_windows.zip

下載下傳後解壓,點選SophixPatchTool.exe 可能會出現無響應等一下就好

# 阿裡熱更新方案

設定響應的參數

# 阿裡熱更新方案

然後點選go,稍等一下,即可生成響應的更新檔:

然後登陸阿裡雲找到對應的移動熱修複進行如下操作即可

# 阿裡熱更新方案
# 阿裡熱更新方案

這樣一個完整的熱修複就做完了,如有疑問請移步到https://help.aliyun.com/document_detail/53247.html?spm=5176.product51340.6.549.ZMQ9JH

繼續閱讀