1. 程式人生 > >一步一步教你實現阿里巴巴的Sophix熱修復(一)

一步一步教你實現阿里巴巴的Sophix熱修復(一)

1.0 整合準備

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.3'

1.1 Sophix許可權新增

<! -- 網路許可權 -->
<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"/>

1.2 配置AndroidManifest檔案

AndroidManifest.xml中間的application節點下新增如下配置:

<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金鑰" />

將上述value中的值分別改為通過平臺HotFix服務申請得到的App Secret和RSA金鑰進行編寫

1.3混淆配置

#基線包使用,生成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.**{*;}
#防止inline
-dontoptimize

1.4  SDK接入

initialize的呼叫應該儘可能的早,必須在Application.attachBaseContext()的最開始(在super.attachBaseContext之後,如果有Multidex,也需要在Multidex.install之後)進行SDK初始化操作,初始化之前不能用到其他自定義類,否則極有可能導致崩潰。而查詢伺服器是否有可用補丁的操作可以在後面的任意地方。不建議在Application.onCreate()中初始化,因為如果帶有ContentProvider,就會使得Sophix初始化時機太遲從而引發問題。

package com.main;

import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;

import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;

/**
 * 入口    2018/9/15.
 */

public class HbApplication extends Application {

    private String TAG = "TAG";

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        initSophix();
    }

    private void initSophix() {
        String appVersion;
        try {
            appVersion = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            appVersion = "1.7.9";
        }

        SophixManager.getInstance().setContext(this)
                .setAppVersion(appVersion)
                .setAesKey(null)
                .setEnableDebug(true)
                .setPatchLoadStatusStub(new PatchLoadStatusListener() {
                    @Override
                    public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
                        // 補丁載入回撥通知
                        if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                            // 表明補丁載入成功
                            Log.e(TAG, "補丁載入成功");
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            // 表明新補丁生效需要重啟. 開發者可提示使用者或者強制重啟;
                            // 建議: 使用者可以監聽進入後臺事件, 然後應用自殺,以此加快應用補丁
                            // 建議呼叫killProcessSafely,詳見1.3.2.3
                            SophixManager.getInstance().killProcessSafely();
                            Log.e(TAG, "表明新補丁生效需要重啟. 開發者可提示使用者或者強制重啟");
                        } else if (code == PatchStatus.CODE_LOAD_FAIL) {
                            // 內部引擎異常, 推薦此時清空本地補丁, 防止失敗補丁重複載入
                            SophixManager.getInstance().cleanPatches();
                            Log.e(TAG, " 內部引擎異常, 推薦此時清空本地補丁, 防止失敗補丁重複載入");
                        } else {
                            // 其它錯誤資訊, 檢視PatchStatus類說明
                            Log.e(TAG, " 其它錯誤資訊," + code);
                        }
                    }
                }).initialize();
        SophixManager.getInstance().queryAndLoadNewPatch();
    }
}

做到這裡就說明配置完成了,接下來就是打補丁包,上傳補丁包了,是不是很期待呢?