1. 程式人生 > >Android最火熱修復實戰

Android最火熱修復實戰

咨詢 ges -perm tencent patch per 存儲 布局 lease

Sophix官網文檔地址
https://help.aliyun.com/document_detail/53240.html

快速接入

項目build.gradle的repositories節點下添加

maven{
      url "http://maven.aliyun.com/nexus/content/repositories/releases"
     }

app目錄build.gradle的dependencies節點下添加

    implementation ‘com.aliyun.ams:alicloud-android-hotfix:3.2.4‘

AndroidManifest.xml裏配置如下權限

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

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

App ID、App Secret和RSA密鑰在阿裏雲控制臺獲取,控制臺傳送門
技術分享圖片
點擊添加產品,然後添加應用
技術分享圖片
應用創建完,點擊 移動熱修復-應用信息 可以看到所需的App ID、App Secret和RSA密鑰
技術分享圖片
技術分享圖片
需要註意的是,AppKey不是App ID,AppKey加上"-1"才是App ID,即25053496-1才是需要的App ID,可以下載如下文件查看App ID
技術分享圖片

Application配置如下

package com.example.zachary.sophix;

import android.app.Application;
import android.content.Context;
import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // queryAndLoadNewPatch不可放在attachBaseContext 中,否則無網絡權限,建議放在後面任意時刻,如onCreate中
        SophixManager.getInstance().queryAndLoadNewPatch();
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        // initialize必須放在attachBaseContext最前面,初始化代碼直接寫在Application類裏面,切勿封裝到其他類。
        SophixManager.getInstance().setContext(this)
                .setAppVersion("1.0.0")
                .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) {
                            // 表明補丁加載成功
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            // 表明新補丁生效需要重啟. 開發者可提示用戶或者強制重啟;
                            // 建議: 用戶可以監聽進入後臺事件, 然後調用killProcessSafely自殺,以此加快應用補丁,詳見1.3.2.3
                        } else {
                            // 其它錯誤信息, 查看PatchStatus類說明
                        }
                    }
                }).initialize();
    }
}

這樣就配置完了,接下來測試一下,在activity布局文件隨便寫幾個字技術分享圖片然後打包安裝到手機技術分享圖片
然後改一下布局文件,再次打包
技術分享圖片

下載補丁生成器,地址:https://help.aliyun.com/document_detail/53247.html?spm=a2c4g.11186623.6.552.76dc4122Tgu7um

技術分享圖片
選擇兩次打包的apk,點擊 GO! 生成補丁
技術分享圖片

打開控制臺,點擊 移動熱修復-補丁管理-上傳補丁技術分享圖片
技術分享圖片
上傳完補丁,點擊詳情
技術分享圖片
點擊新建發布,選擇全量發布,(灰色發布大概是隨機選擇幾個目標測試,減少風險)
技術分享圖片
發布成功後,殺掉剛才安裝帶有“天王蓋地虎”內容的安裝包,重新打開,發現內容變成“寶塔鎮河妖”,說明熱修復成功!
技術分享圖片

穩健接入

穩健接入和快速接入的差異主要在Application的配置上,其他配置都一樣,新建一個SophixStubApplication類,配置如下

package com.example.zachary.sophix;

import android.content.Context;
import android.support.annotation.Keep;
import android.util.Log;
import com.taobao.sophix.PatchStatus;
import com.taobao.sophix.SophixApplication;
import com.taobao.sophix.SophixEntry;
import com.taobao.sophix.SophixManager;
import com.taobao.sophix.listener.PatchLoadStatusListener;
/**
 * 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(MyRealApplication.class)
    static class RealApplicationStub {}
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        //如果需要使用MultiDex,需要在此處調用。
        //MultiDex.install(this);
        initSophix();
    }
    private void initSophix() {
        String appVersion = "1.0.0";//和build.gradle配置的要一致
        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) {
                        if (code == PatchStatus.CODE_LOAD_SUCCESS) {
                            Log.i(TAG, "sophix load patch success!");
                        } else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
                            //如果需要在後臺重啟,建議此處用SharePreference保存狀態。
                            Log.i(TAG, "sophix preload patch success. restart app to make effect.");
                        }
                    }
                }).initialize();
    }
}

MyRealApplication就是我們項目中自己的Application,需要在onCreate裏添加如下代碼

public class MyRealApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //queryAndLoadNewPatch不可放在attachBaseContext 中,否則無網絡權限,建議放在後面任意時刻,如onCreate中
        SophixManager.getInstance().queryAndLoadNewPatch();
    }
}

然後在AndroidManifest.xml中聲明SophixStubApplication技術分享圖片記住是SophixStubApplication,而不是項目本來的Application,這跟微信的熱修復框架Tinker有點類似啊哈哈~~

項目已上傳Github: https://github.com/Zachary46/Sophix

技術分享圖片

Android最火熱修復實戰