本文更新于2017年11月20日
- studio添加依賴(lài):
gradle遠(yuǎn)程倉(cāng)庫(kù)依賴(lài), 打開(kāi)項(xiàng)目找到app的build.gradle文件,添加如下配置:
添加maven倉(cāng)庫(kù)地址:
repositories {
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
添加gradle坐標(biāo)版本依賴(lài):
compile 'com.aliyun.ams:alicloud-android-hotfix:3.1.6'
-
配置AndroidManifest文件
-
需要用到一下權(quán)限:
<! -- 網(wǎng)絡(luò)權(quán)限 --> <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" /> <! -- 外部存儲(chǔ)讀權(quán)限切威,調(diào)試工具加載本地補(bǔ)丁需要 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
READ_EXTERNAL_STORAGE
權(quán)限屬于Dangerous Permissions娜膘,僅調(diào)試工具獲取外部補(bǔ)丁需要惜辑,不影響線(xiàn)上發(fā)布的補(bǔ)丁加載涕刚,調(diào)試時(shí)請(qǐng)自行做好android6.0以上的運(yùn)行時(shí)權(quán)限獲取儡毕。 -
application節(jié)點(diǎn)下添加如下配置:添加AppId,AppSecret,RSA密鑰
<meta-data android:name="com.taobao.android.hotfix.IDSECRET" android:value="AppId" /> <meta-data android:name="com.taobao.android.hotfix.APPSECRET" android:value="AppSecret" /> <meta-data android:name="com.taobao.android.hotfix.RSASECRET" android:value="RSA密鑰" />
如何獲取AppId,AppSecret,RSA密鑰交排,不知道的請(qǐng)看我的sophix集成系列第一篇:阿里最新熱修復(fù)框架sophix集成詳解(一):控制臺(tái)開(kāi)通移動(dòng)熱修復(fù)
因?yàn)锳ppSecret和RSA密鑰比較敏感划滋,出于安全考慮,可以在代碼中通過(guò)setSecretMetaData這個(gè)方法進(jìn)行設(shè)置埃篓。這個(gè)下面寫(xiě)Java代碼時(shí)再說(shuō)处坪。
-
-
混淆配置
#基線(xiàn)包使用,生成mapping.txt -printmapping mapping.txt #生成的mapping.txt在app/buidl/outputs/mapping/release路徑下,移動(dòng)到/app路徑下 #修復(fù)后的項(xiàng)目使用同窘,保證混淆結(jié)果一致 #-applymapping mapping.txt #hotfix -keep class com.taobao.sophix.**{*;} -keep class com.ta.utdid2.device.**{*;} #防止inline -dontoptimize
Java代碼初始化接入
Sophix 3.1.6版本以后引入了新的初始化方式玄帕。
原來(lái)的初始化方式仍然可以使用,不過(guò)新方式將會(huì)帶來(lái)以下優(yōu)點(diǎn):初始化與應(yīng)用原先業(yè)務(wù)代碼完全隔離想邦,使得原先真正的Application可以修復(fù)裤纹,并且減少了補(bǔ)丁預(yù)加載時(shí)間。而且丧没,新方式已經(jīng)優(yōu)先支持Android 8.0版本鹰椒。
本文使用這種新型方式。
1- 導(dǎo)入SophixStubApplication
需要加入這個(gè)類(lèi):
package com.my.pkg;
import android.app.Application;
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;
import com.my.pkg.MyRealApplication;
/**
* Sophix入口類(lèi)骂铁,專(zhuān)門(mén)用于初始化Sophix吹零,不應(yīng)包含任何業(yè)務(wù)邏輯。
* 此類(lèi)必須繼承自SophixApplication拉庵,onCreate方法不需要實(shí)現(xiàn)灿椅。
* AndroidManifest中設(shè)置application為此類(lèi),而SophixEntry中設(shè)為原先Application類(lèi)钞支。
* 注意原先Application里不需要再重復(fù)初始化Sophix茫蛹,并且需要避免混淆原先Application類(lèi)。
* 如有其它自定義改造烁挟,請(qǐng)咨詢(xún)官方后妥善處理婴洼。
*/
public class SophixStubApplication extends SophixApplication {
private final String TAG = "SophixStubApplication";
// 此處SophixEntry應(yīng)指定真正的Application,也就是你的應(yīng)用中原有的主Application撼嗓,并且保證RealApplicationStub類(lèi)名不被混淆柬采。
@Keep
@SophixEntry(MyRealApplication.class)
static class RealApplicationStub {}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 如果需要使用MultiDex,需要在此處調(diào)用且警。
// MultiDex.install(this);
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) //三個(gè)參數(shù)分別對(duì)應(yīng)AndroidManifest里面的AppId粉捻、AppSecret、RSA密鑰斑芜,可以不在AndroidManifest設(shè)置而是用此函數(shù)來(lái)設(shè)置Secret肩刃。放到代碼里面進(jìn)行設(shè)置可以自定義混淆代碼,更加安全杏头,此函數(shù)的設(shè)置會(huì)覆蓋AndroidManifest里面的設(shè)置盈包,如果對(duì)應(yīng)的值設(shè)為null,默認(rèn)會(huì)在使用AndroidManifest里面的醇王。
.setEnableDebug(true)//默認(rèn)為false呢燥,設(shè)為true即調(diào)試模式下會(huì)輸出日志以及不進(jìn)行補(bǔ)丁簽名校驗(yàn). 線(xiàn)下調(diào)試此參數(shù)可以設(shè)置為true, 它會(huì)強(qiáng)制不對(duì)補(bǔ)丁進(jìn)行簽名校驗(yàn), 所有就算補(bǔ)丁未簽名或者簽名失敗也發(fā)現(xiàn)可以加載成功. 但是正式發(fā)布該參數(shù)必須為false, false會(huì)對(duì)補(bǔ)丁做簽名校驗(yàn), 否則就可能存在安全漏洞風(fēng)險(xiǎn)。
.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) {
// 如果需要在后臺(tái)重啟寓娩,建議此處用SharePreference保存狀態(tài)叛氨。
Log.i(TAG, "sophix preload patch success. restart app to make effect.");
/** 不可以直接Process.killProcess(Process.myPid())來(lái)殺進(jìn)程滥朱,這樣會(huì)擾亂Sophix的內(nèi)部狀態(tài)。
* 因此如果需要?dú)⑺肋M(jìn)程力试,建議使用這個(gè)方法徙邻,它在內(nèi)部做一些適當(dāng)處理后才殺死本進(jìn)程。*/
instance.killProcessSafely();
}
}
}).initialize();
}
@Override
public void onCreate() {
super.onCreate();
// queryAndLoadNewPatch不可放在attachBaseContext 中畸裳,否則無(wú)網(wǎng)絡(luò)權(quán)限缰犁,建議放在后面任意時(shí)刻,如onCreate中
SophixManager.getInstance().queryAndLoadNewPatch();
/** 補(bǔ)丁在后臺(tái)發(fā)布之后, 并不會(huì)主動(dòng)下行推送到客戶(hù)端, 客戶(hù)端通過(guò)調(diào)用queryAndLoadNewPatch方法查詢(xún)后臺(tái)補(bǔ)丁是否可用*/
}
}
初始化sophix務(wù)必放在attachBaseContext中怖糊,onCreate不需要自行實(shí)現(xiàn)帅容。同時(shí)自定義的SophixStubApplication需要繼承com.taobao.sophix.SophixApplication。
這其中伍伤,關(guān)鍵一點(diǎn)是:
@Keep
@SophixEntry(MyRealApplication.class)
static class RealApplicationStub {}
SophixEntry應(yīng)指定項(xiàng)目中原先真正的Application(原項(xiàng)目里application的android::name指定的)并徘,這里用MyRealApplication指代。并且保證RealApplicationStub類(lèi)名不被混淆扰魂。而SophixStubApplication的類(lèi)名和包名可以自行取名麦乞。
這里的Keep是android.support包中的類(lèi),目的是為了防止這個(gè)內(nèi)部靜態(tài)類(lèi)的類(lèi)名被混淆劝评,因?yàn)閟ophix內(nèi)部會(huì)反射獲取這個(gè)類(lèi)的SophixEntry姐直。如果項(xiàng)目中沒(méi)有依賴(lài)android.support的話(huà),就需要在progurad里面手動(dòng)指定RealApplicationStub不被混淆蒋畜。
2- 然后声畏,在proguard文件里面需要加上下面內(nèi)容:
-keepclassmembers class com.my.pkg.MyRealApplication {
public <init>();
}
# 如果不使用android.support.annotation.Keep則需加上此行
# -keep class com.my.pkg.SophixStubApplication$RealApplicationStub
目的是防止真正Application的構(gòu)造方法被proguard混淆。
最后姻成,需要把AndroidManifest里面的application改為這個(gè)新增的SophixStubApplication類(lèi):
<application
android:name="com.my.pkg.SophixStubApplication"
... ...>
... ...
sample源碼
下一篇插龄,阿里最新熱修復(fù)框架sophix集成詳解(三):生成、上傳科展、調(diào)試補(bǔ)丁