接入說明
instantRun 方式僅支援原生 AAR 接入方式。
InstantRun 新特性
滿足一定條件下,支援不重啟修複;
支援 so 修複 ;
支援資源修複;
產生補丁的時候不需要類白名單。
技術原理
Java 修複
通過對 JavaMethod 進行預插樁,實現動態邏輯替換。
構建 Patch 需要修改源碼,因此無法修改代碼的三方庫不能實現修複。
so 修複
原始 so 未載入可立即生效。
資源修複
通過固定資源 ID 而進行新增和修改。
前置條件
採用原生 AAR 方式接入,需要先 將 mPaaS 添加到您的專案中。
不要混用 dexPatch 熱修複方式和 instantRun 熱修複方式。
新舊 APK 包中的 so 檔案數量和名字需要保持一致,否則無法打出熱修複補丁且不支援修複。
必須使用 10.2.3.20 及以上 基準版本,如你是 10.1.68 基準版本,請按照文檔進行 mPaaS 10.2.3 升級指南。
添加 SDK
原生 AAR 方式
參考 管理組件依賴,通過 組件管理(AAR)在工程中安裝 熱修複(Hotfix)組件。
初始化熱修複
原生 AAR 接入
如果需要使用熱修複功能,您還需要完成以下兩步操作。
需要將
Application對象重新繼承為QuinoxlessApplicationLike,並注意將該類防混淆。此處以 MyApplication 為例。@Keep public class MyApplication extends QuinoxlessApplicationLike implements Application.ActivityLifecycleCallbacks { private static final String TAG = "MyApplication"; @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); Log.i(TAG, "attacheBaseContext"); } @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate"); registerActivityLifecycleCallbacks(this); } @Override public void onMPaaSFrameworkInitFinished() { MPHotpatch.init(); LoggerFactory.getTraceLogger().info(TAG, getProcessName()); } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log.i(TAG, "onActivityCreated"); } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } }在 AndroidManifest.xml 檔案中將
Application對象指向 mPaaS 提供的Application對象。將剛剛產生的 MyApplication 類添加到 key 為mpaas.quinoxless.extern.application的meta-data中。樣本如下:<application android:name="com.alipay.mobile.framework.quinoxless.QuinoxlessApplication" > <meta-data android:name="mpaas.quinoxless.extern.application" android:value="com.mpaas.demo.MyApplication" /> </application>其中
com.mpaas.demo.MyApplication是您自訂的 Application 代理類,繼承QuinoxlessApplicationLike。引入 Apache HTTP 用戶端。
在使用熱修複功能的時候,需要調用到 Apache HTTP 用戶端相關的功能。只需在
AndroidManifest.xml加入如下代碼。更多資訊,請參見使用 Apache HTTP 用戶端。<uses-library android:name="org.apache.http.legacy" android:required="false"/>
instantRun 插樁配置和依賴
instantRun Maven
maven {
url "https://mvn.cloud.alipay.com/nexus/content/repositories/open/"
}instantRun 插樁依賴
工程 app 主 module 下 build.gradle 檔案中添加如下依賴:
apply plugin: 'com.android.application'
apply plugin: 'com.alipay.instantrun'工程根目錄下 build.gradle 檔案中添加如下外掛程式依賴:
如果您的專案中使用的 AGP >= 8.0,則需使用 1.0.8 版本的外掛程式依賴;如果 AGP < 8.0,則需使用 1.0.7 版本的外掛程式依賴。
dependencies {
classpath "com.mpaas.android.patch:patch-gradle-plugin:1.0.8"
}instantRun 插樁配置
建立 instantrun 檔案夾
在主工程的 app 目錄下建立 instantrun 檔案夾,放入產生 patch.jar 需要使用的 mapping.txt 檔案。
instantrun 檔案夾中檔案的說明及來源按以下方式操作放入:
以下檔案必須在每次發布版本前進行保留,當需要修複時需將上個版本保留好的檔案替換到 instantrun 檔案夾中。
在有 Bug 的專案工程中執行命令列 ./gradlew clean assembleRelease產生以下檔案:
instantrun/InstantRunMapping.txt.gz(構建後產生的 InstantRunMapping_release.txt.gz 或 InstantRunMapping_debug.txt.gz,產物在 ./build/outputs/instantrun/ 如有,則改名後放入)
instantrun/mapping.txt(原工程構建打 Release 包時的 mapping.txt,產物在 ./build/outputs/mapping/[debug|release]/mapping.txt)
instantrun/methodsMap.instantrun(原 Bundle 層級接入插樁產生的 methodsMap.instantrun,產物在./build/outputs/instantrun/methodsMap.instantrun 如有則放入)添加 instantrun.xml 設定檔
在主工程的 app 目錄下添加 instantrun.xml設定檔,注意配置中的相關內容,請仔細斟酌每個選項:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<switch>
<!--true代表開啟InstantRun,請注意即使這個值為true,InstantRun也預設只在Release模式下開啟-->
<!--false代表關閉InstantRun,無論是Debug還是Release模式都不會運行InstantRun-->
<turnOnInstantRun>true</turnOnInstantRun>
<!--是否開啟手動模式,手動模式會去尋找配置項patchPackageName包名下的所有類,自動的處理混淆,然後把patchPackageName包名下的所有類製作成補丁-->
<!--這個開關只是把配置項patchPackageName包名下的所有類製作成補丁,適用於特殊情況,一般不會遇到-->
<manual>false</manual>
<!--是否強制插入代碼,InstantRun預設在debug模式下是關閉的,開啟這個選項為true會在debug下插入代碼-->
<!--但是當配置項turnOnInstantRun是false時,這個配置項不會生效-->
<forceInsert>false</forceInsert>
<!--配置Patch函數匹配規則,預設為函數簽名,可修改為函數序號,儲存在methodsMap.instantrun中-->
<!--其中signature模式切面佔用空間較大,而id模式切面佔用空間會更小一些,更適合在乎安裝包大小的App使用-->
<!--<methodMatchMode>signature</methodMatchMode>-->
<methodMatchMode>id</methodMatchMode>
<!--是否捕獲補丁中所有異常,建議上線的時候這個開關的值為true,測試的時候為false-->
<catchReflectException>false</catchReflectException>
<!--是否在補丁加上log,建議上線的時候這個開關的值為false,測試的時候為true-->
<patchLog>true</patchLog>
<!--專案是否支援progaurd-->
<proguard>true</proguard>
</switch>
<!--需要HotPatch的包名或者類名,這些包名下的所有類都會被插入代碼-->
<!--這個配置項是各個Bundle需要自行配置,就是你們Bundle裡面你們自己代碼的包名,
這些包名下的類會被InstantRun插入代碼,沒有被InstantRun插入代碼的類InstantRun是無法修複的-->
<acceptPackageName name="acceptPackage">
<name>com.</name>
<name>android.</name>
<name>org.</name>
</acceptPackageName>
<!--不需要InstantRun插入代碼的包名,InstantRun庫不需要插入代碼,如下的配置項請保留,還可以根據各個APP的情況執行添加-->
<exceptPackageName name="exceptPackage">
<name>com.alipay.euler</name>
<name>com.alipay.dexpatch</name>
<name>com.alipay.instantrun</name>
<name>ohos.</name>
<name>com.alipay.mobile.quinox.LauncherApplication</name>
</exceptPackageName>
<!--不需要InstantRun插樁的函數訪問類型和對應包名列表,按需插樁,可降低接入包大小-->
<methodExceptConfig name="methodExceptConfig">
<privateMethodPackage>
<name>com.instantrun.demo</name>
</privateMethodPackage>
<packageMethodPackage>
<name>com.instantrun.demo</name>
</packageMethodPackage>
<protectedMethodPackage>
<name>com.instantrun.demo</name>
</protectedMethodPackage>
<publicMethodPackage>
<name>com.instantrun.demo</name>
</publicMethodPackage>
<syntheticMethodPackage>
<name>com.instantrun.demo</name>
</syntheticMethodPackage>
</methodExceptConfig>
<!--補丁的包名,請保證唯一性,填寫apk包名即可-->
<patchPackageName name="patchPackage">
<name>com.instantrun.demo</name>
</patchPackageName>
</resources>修改 Bug 代碼
Java 函數修複方式
首先接入上述的構建依賴與配置;
需要在改動的方法上面添加以下註解:
@com.alipay.instantrun.patch.annotaion.Modify//修改方法 @com.alipay.instantrun.patch.annotaion.Modify protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } //或者是被修改的方法裡面調用 com.alipay.instantrun.patch.InstantRunModify.modify()方法 protected void onCreate(Bundle savedInstanceState) { com.alipay.instantrun.patch.InstantRunModify.modify() super.onCreate(savedInstanceState); }對於 Lambda 運算式,需要在修改的方法裡面調用:
com.alipay.instantrun.patch.InstantRunModify.modify()。//修改方法 @com.alipay.instantrun.patch.annotaion.Modify protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } //或者是被修改的方法裡面調用com.alipay.instantrun.patch.InstantRunModify.modify()方法 protected void onCreate(Bundle savedInstanceState) { com.alipay.instantrun.patch.InstantRunModify.modify() super.onCreate(savedInstanceState); }新增的類、方法使用
@com.alipay.instantrun.patch.annotaion.Add註解。//增加方法 @com.alipay.instantrun.patch.annotaion.Add public String getString() { return "InstantRun"; } //增加類 @com.alipay.instantrun.patch.annotaion.Add public class NewAddCLass { public static String get() { return "instantRun"; } }
so 修複方式
修改相關 C/C++ 代碼或 so 即可,然後打包新的 so 替換工程中有問題的 so 庫。
資源修複方式
支援任何資源檔的修複和添加,但不支援 so 庫資源的添加。
資源 ID 固定配置
下載 產生資源檔的工具 Jar 包 擷取需要修複的 apk 包資源 id,執行以下命令列:
java -jar ~/path/stableResourcesId.jar ~/path/old.apk ~/path/values產生的產物在目標目錄下。
將上面命令列產生的
public.xml、ids.xml兩個檔案產物放入到新工程(修複好的工程)的~/res/values目錄中。將
public.txt檔案放入到新工程(修複好的工程)的根目錄中。然後在 app module 的
build.gradle檔案中的 android 節點下進行如下配置:aaptOptions { File publicTxtFile = project.rootProject.file( 'public.txt') if (publicTxtFile.exists()) { additionalParameters "--stable-ids", "${project.rootProject.file ('public.txt').absolutePath}" } }
進行補丁打包配置
在 Android Studio 的 mPaaS 外掛程式中,進入 基礎工具 > 熱修複 > 產生補丁(instant run)頁面。
說明
如果是修改或者新增 res/layout 下的 xml 布局檔案,則需在 Java 代碼層進行 Java patch 加入修改的註解以及擷取對應的資源 id,再進行載入。
使用 instantRun
產生 patch.jar 產物
patch.jar 是產生熱修複補丁包的關鍵,包含了需要修複的內容,在最新修複的工程輸出即可,在終端按如下命令列執行產生:
./gradlew clean mpGeneratePatch產生的產物在工程的 ./build/outputs/instantrun/patch.jar目錄下。
產生熱修複 instantRun 補丁
在 Android Studio 的 mPaaS 外掛程式工程中進行補丁產生,如下所示:
單擊 基礎工具 > 熱修複 > 產生補丁(instant run)。
進入產生補丁頁面,填寫相關修複資訊項。
輸入項含義說明
New bundle:選擇最新修複好的 apk 包路徑。
Old bundle:選擇有 bug 的 APK 包路徑(線上版本)。
PatchJarPath dir:工程中接入 instantRun 執行命令列
./gradlew clean mpGeneratePatch打出的patch.jar路徑。Patch out dir:存放補丁包產物的路徑。
重要New bundle 和 Old bundle 中的 apk 包不能存放到 C 盤的 User 目錄下和中文目錄下。
單擊 Next 進入填寫簽名資訊頁面。
確保填寫的簽名資訊準確,否則會導致產生失敗。
填寫完成後單擊 Create 即可產生補丁。
使用熱修複
將補丁包發布到控制台,具體參考文檔 使用熱修複。
查看日誌
熱更新要求日誌
過濾 Tag 中包含 DynamicRelease 的日誌;
InstantRun 執行日誌
過濾 Tag 中包含 IR. 的日誌;
Patch 執行日誌
在打 Patch 前,在構建配置 instantrun.xml 中開啟 patchLog 選項。 過濾 Tag 中包含 IR.PatchCode 的日誌。包含 invoke method is 的日誌行,表示執行了對應函數的 Patch。