Android熱修復之Sophix

一、爲啥用熱修復?

Apk難免出現bug。有了bug咋辦?

發新版?
強更嗎?用戶體驗不好。不強更?bug怎麼修復啊!
再者,發新版要打包、加固、上線、審覈等一系列婆婆媽媽的事情,bug肯定不能及時修復。

此時,熱修復登場了,短時間查找修復bug,生成補丁上傳,一般一小時內就可以解決bug。
小情況,可以即時生效;略大情況,冷啓動下次也可以修復在線bug。

二、熱修復的選擇

國內大廠基本都有自己的熱修復工具,So,我們小廠可以選擇參考借用。

1、阿里系
	AndFix	開源,實時生效
	HotFix	阿里百川,未開源,免費、實時生效
	Sophix	未開源,商業收費,實時生效/冷啓動修復
	HotFix是AndFix的優化版本,Sophix是HotFix的優化版本。目前阿里系主推是Sophix。

2、騰訊系
	Qzone超級補丁	QQ空間,未開源,冷啓動修復
	QFix	手Q團隊,開源,冷啓動修復
	Tinker	微信團隊,開源,冷啓動修復。提供分發管理,基礎版免費
	
3、其他
	Robust	美團, 開源,實時修復
	Nuwa	大衆點評,開源,冷啓動修復
	Amigo	餓了麼,開源,冷啓動修復

彙總:選擇Tinker或者Sophix。鑑於阿里號稱第一Java大廠,所以我選Sophix。
哈哈。其實:
有些人可能考慮免費AndFix、HotFix,但github給出的代碼並不好,而且兩年多不更新。而且作爲它們的升級版,應該選Sophix方案。
Sophix提供了一套更加完美的客戶端服務端一體的熱更新方案,做到了圖形界面一鍵打包、加密傳輸、簽名校驗和服務端控制發佈與灰度功能,讓你用最少的時間實現最強大可靠的全方位熱更新。

三、Sophix的接入

借鑑官方文檔and加以提煉補充

引入

gradle遠程倉庫依賴, 打開項目找到app的build.gradle文件,添加如下配置:

添加maven倉庫地址:
repositories {
	maven {
		url "http://maven.aliyun.com/nexus/content/repositories/releases"
	}
}

添加gradle座標版本依賴:
	compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.12'

配置AndroidManifest文件

添加權限
<! -- 網絡權限 -->
<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"/>

注意:READ_EXTERNAL_STORAGE權限屬於Dangerous Permissions,僅調試工具獲取外部補丁需要,不影響 線上發佈的補丁加載,調試時請自行做好android6.0以上的運行時權限獲取。

替換application的name
<application
    android:name="com.my.pkg.SophixStubApplication"
    ... ...>
    ... ...
配置id、Secrect、Rsa
//該三項配置也可在SophixApplication中進行配置,配置注意不要多空格或少複製,尤其RSA等問題
<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密鑰" /

混淆配置

#基線包使用,生成mapping.txt
-printmapping mapping.txt
#生成的mapping.txt在app/build/outputs/mapping/release路徑下,移動到/app路徑下

#修復後的項目使用,保證混淆結果一致
#-applymapping mapping.txt

#hotfix
-keep class com.taobao.sophix.**{*;}
-keep class com.ta.utdid2.device.**{*;}
-dontwarn com.alibaba.sdk.android.utils.**
#防止inline
-dontoptimize

引入配置類

/**
 * Sophix入口類,專門用於初始化Sophix,不應包含任何業務邏輯。
 * 此類必須繼承自SophixApplication,onCreate方法不需要實現。
 * 此類不應與項目中的其他類有任何互相調用的邏輯,必須完全做到隔離。
 * AndroidManifest中設置application爲此類,而SophixEntry中設爲原先Application類。
 * 注意原先Application裏不需要再重複初始化Sophix,並且需要避免混淆原先Application類。
 * 如有其它自定義改造,請諮詢官方後妥善處理。
 */
public class SophixStubApplication extends SophixApplication {
    private final String TAG = "SophixStubApplication";

    // 此處SophixEntry應指定真正的Application,並且保證RealApplicationStub類名不被混淆。
    @Keep
    @SophixEntry(BaseApplication.class)
    static class RealApplicationStub {
    }
    //上面這個類不要動

    public static final String LOADED = "loaded";
    public static final String PRELOADED = "preloaded";

    private Context mContext = null;

    public static CallBackLoadedPatch callBackLoadedPatch;

    public static void getData(CallBackLoadedPatch callBackLoadedPatch){
        SophixStubApplication.callBackLoadedPatch = callBackLoadedPatch;
    }
    public interface CallBackLoadedPatch{
       void setData(String s);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
//         如果需要使用MultiDex,需要在此處調用。
//         MultiDex.install(this);
        mContext = base;
        initSophix();
    }

    private void initSophix() {
        String appVersion = "0.0.0";
        try {
            appVersion = this.getPackageManager()
                    .getPackageInfo(this.getPackageName(), 0)
                    .versionName;
        } catch (Exception e) {
        }
        final SophixManager instance = SophixManager.getInstance();
        instance.setContext(this)
                .setAppVersion(appVersion)
                .setSecretMetaData(null, null, null)
                .setEnableDebug(true)
                .setEnableFullLog()
                .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                    @Override
                    public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                        //handlePatchVersion當前處理的補丁版本號, 0:無  -1:本地補丁  其它:後臺補丁
                        if (code == PatchStatus.CODE_LOAD_SUCCESS) { //加載成功
                        	//如需要判斷patch版本,保存加載成功patch版本,可在此處理

                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) { //預加載階段,需要重啓
                            // 如果需要在後臺重啓,建議此處用SharePreference保存狀態。
              
                        } else {
                            // 其它錯誤信息, 查看PatchStatus類說明
                        }
                    }
                }).initialize();
    }
}
查詢補丁並加載
在代碼相應類中,調用以下方法,進去查詢並加載補丁 
//注意該接口的調用涉及收費,下一部分提供一個簡單的降費策略。
queryAndLoadNewPatch()

至此:你便完成了補丁的加載。

四、補丁的生成

需要下載:SophixPatchTool.exe 去使用新舊app去生成差異補丁。
注意事項:
	 生成補丁時:
	 		高級配置默認選中:
		 		強制冷啓動:所以,即時生效不會生效。
		 		檢查初始化:
		 		快速打包:
		 		優化資源補丁:
	 		未選中:
	 			不比較資源
	 				不比較So庫
	 				  
	 		設置:基本不動修改。

五、補丁的測試

		 1、手機安卓old apk
		 2、手機安卓 Sophix調試工具.apk
		 3、方式1:通過掃阿里雲控制後臺二維碼測試
		 	  方式2:通過補丁copy到手機,引用本地補丁測試

六、補丁的發佈

目前阿里雲只提供了,官方後臺發佈、管理補丁,不對外提供相關操作接口,所以我們就用下他們的後臺吧。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20191223182000445.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hnaGdsZw==,size_16,color_FFFFFF,t_70)

圖形界面操作,沒啥好說的,提幾點注意事項:
	1、每個應用版本,對應若干補丁;
	2、同一時間段,只會有一個補丁生效,新補丁的的發佈會覆蓋掉舊補丁。
	3、補丁回滾:該版本號下,有過全量發佈,而且不是手動點的停止,可以回滾,其他的都不能回滾
	4、掃描驗證補丁:在發佈詳情內,我們可以使用測試即將發佈的補丁。
	5、 過濾機型、統計加載數據等功能都比較一般。

七、優化發佈

需求1:只有AndroidX版本出現問題,只想熱更X版本怎麼辦?
需求2:頻繁調用 queryAndLoadNewPatch() 引發收費問題怎麼辦?

此時:我們可以主動提供一個後臺接口
		請求: 安卓版本號,
		返回:補丁id、修復Android版本、是否強更
		
		代碼處理:
		判斷補丁不存在,不處理;
		補丁存在,判斷安卓版本;補丁版本存在於本地,不處理;
		新補丁(包括第一次)存在,判斷強更強更,非強更默認更。

八、注意事項

1. Sophix SDK版本

	3.2.11 // AndroidX的資源庫兼容
	           Android 10的加固兼容    
	3.2.10            
	3.2.9 //2019-10-18  支持安卓10系統
	3.2.8 //2018-11-30  增加埋點信息
	
	3.2.7 //2018-11-13  補丁包tag feather
	                    sdk穩定性增強
	                    P版本強制穩健接入
	3.2.6 //2018-9-19   支持自定義classLoader下的getResourceAsStream
	                    兼容索尼低版本機型資源修復
	                    
	3.2.4 //2018-6-27   支持安卓P dp3
	                    修復8.x版本JIT問題
	                    修復穩定接入初次啓動幫後偶現問題
	3.2.3 //2018-5-15  完善崩潰清除機制
	                   修復360加固標誌識別問題

2. 阿里雲後臺相關

注意區分:安卓版本號、引用版本號、補丁版本號、批次號
				批次號是補丁的唯一標識,批次號即爲回調方法
				onLoad(final int mode, final int code, final String info, final int handlePatchVersion) 
				 中 handlePatchVersion
發佈了8 篇原創文章 · 獲贊 5 · 訪問量 1737
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章