Android最火熱修復實戰
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最火熱修復實戰