最近一周公司項(xiàng)目已經(jīng)上線了,暫時(shí)沒(méi)有接到比較重要的任務(wù)唉俗,工作量相對(duì)比較少闹司,于是決定搞一波事情娱仔,思來(lái)想去,把目標(biāo)對(duì)準(zhǔn)了熱修復(fù)开仰。熱修復(fù)作為當(dāng)下熱門的技術(shù)拟枚,在業(yè)界內(nèi)比較著名的有阿里系的AndFix、Sophix众弓,騰訊QQ空間的超級(jí)補(bǔ)丁技術(shù)和微信的Tinker恩溅。由于最近一段時(shí)間了解到阿里發(fā)布了新一代熱修復(fù)技術(shù)—Sophix,聽(tīng)說(shuō)挺牛逼的樣子谓娃,于是我決定折騰一下脚乡。
為什么要引入熱修復(fù)?
當(dāng) App 上線以后,如果出現(xiàn)比較嚴(yán)重的bug奶稠,實(shí)在很著急……有時(shí)候僅僅是為了修改了幾行代碼俯艰,也要付出巨大的成本,你需要修復(fù)bug锌订,重新測(cè)試竹握,確保無(wú)誤后,重新打包辆飘,發(fā)版到應(yīng)用市場(chǎng)啦辐,等待通過(guò)審核,再等到用戶下載更新的冗長(zhǎng)路徑蜈项,有的用戶甚至對(duì)頻繁發(fā)版的APP會(huì)有抵觸而不更新芹关。所以引入了熱修復(fù)這個(gè)技術(shù),阿里百川的解釋是:無(wú)需發(fā)新版本紧卒,無(wú)需等待用戶更新侥衬,基于阿里巴巴首創(chuàng)Hotpatch技術(shù),實(shí)時(shí)修復(fù)應(yīng)用線上問(wèn)題跑芳。阿里百川HotFix能夠幫助開(kāi)發(fā)者將修復(fù)Bug的補(bǔ)丁轴总,實(shí)時(shí)發(fā)布到APP內(nèi),當(dāng)用戶啟動(dòng)APP時(shí)聋亡,補(bǔ)丁將自動(dòng)加載安裝肘习,用戶全程無(wú)感知,而B(niǎo)ug已經(jīng)修復(fù)坡倔,最后還會(huì)自動(dòng)刪除補(bǔ)丁哦漂佩。
到這里,大家應(yīng)該對(duì)它有個(gè)大致了解了罪塔,可能也有不少人對(duì)這個(gè)補(bǔ)丁還比較疑惑投蝉,不知道什么東西,至少我一開(kāi)始是這樣的征堪,客官瘩缆,別急,在文章后面會(huì)慢慢為你分析佃蚜,下面就和大家一步步來(lái)入手學(xué)習(xí)SoPhix吧庸娱。
1、首先要注冊(cè)阿里百川賬號(hào)
可以使用淘寶賬號(hào)進(jìn)行注冊(cè)谐算,非常方便:
2.創(chuàng)建應(yīng)用
創(chuàng)建應(yīng)用熟尉,填入相關(guān)信息
填完了之后會(huì)自動(dòng)提供給你appkey和AppSecret,這個(gè)在后面構(gòu)建項(xiàng)目的時(shí)候會(huì)用到
3.申請(qǐng)產(chǎn)品權(quán)限
在百川開(kāi)發(fā)者控制臺(tái)申請(qǐng)HotFix產(chǎn)品權(quán)限洲脂,官方將在1個(gè)工作日內(nèi)完成審批斤儿。申請(qǐng)理由請(qǐng)“填寫您真實(shí)的APP名,說(shuō)明是否已上應(yīng)用市場(chǎng),通過(guò)什么渠道了解到百川HotFix往果。若無(wú)APP或還未上線請(qǐng)?jiān)敿?xì)描述具體公司業(yè)務(wù)疆液。
以上準(zhǔn)備工作完成了之后,就可以進(jìn)行集成使用了
1陕贮、先進(jìn)入Sophix官網(wǎng)首頁(yè)
可以直接用淘寶賬號(hào)登錄堕油,非常便捷,
2肮之、選擇移動(dòng)熱修復(fù)馍迄,就會(huì)看到這個(gè)頁(yè)面,點(diǎn)擊管理控制臺(tái)
3局骤、進(jìn)入后臺(tái)管理頁(yè)面
4、選擇你需要的那一項(xiàng)點(diǎn)擊管理暴凑,進(jìn)入下一個(gè)頁(yè)面
下面開(kāi)始代碼集成學(xué)習(xí)
阿里百川Sophix官方文檔學(xué)習(xí)
1峦甩、在Project和app中的build.gradle中分別配置maven倉(cāng)庫(kù)和添加如下依賴
添加maven倉(cāng)庫(kù)地址:
repositories {
maven {
url "http://maven.aliyun.com/nexus/content/repositories/releases"
}
}
添加app的build.gradle依賴:
compile 'com.aliyun.ams:alicloud-android-hotfix:3.1.1'
//傳遞性依賴utdid這個(gè)sdk, 所以不需要重復(fù)依賴utdid.但是另一方面其它阿里系SDK也可能依賴了
//utdid這個(gè)SDK, 如果編譯期間報(bào)utdid重復(fù), 所以此時(shí)進(jìn)行如下處理即可, 關(guān)閉傳遞性依賴:
compile ('com.aliyun.ams:alicloud-android-hotfix:3.1.1') {
exclude(module:'alicloud-android-utdid')
}
2 . 在AndroidManifest文件中添加Sophix權(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/ACCESS_WIFI_STATE權(quán)限屬于Dangerous Permissions,自行做好android6.0以上的運(yùn)行時(shí)權(quán)限獲取
3 . 在AndroidManifest文件中配置創(chuàng)建應(yīng)用時(shí)獲取到的appId现喳、appSecret凯傲、rsa秘鑰(替換成你自己的哈,可以在你的應(yīng)用那里查看)
<meta-data
android:name="com.taobao.android.hotfix.IDSECRET"
android:value="your App ID" />
<meta-data
android:name="com.taobao.android.hotfix.APPSECRET"
android:value="your App Secret" />
<meta-data
android:name="com.taobao.android.hotfix.RSASECRET"
android:value="your RSA密鑰" />
4 . 新建Application子類
在attachBaseContext初始化SophixManager
在onCreate中查詢服務(wù)器是否有新的可用補(bǔ)丁
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 查詢服務(wù)器是否有可用補(bǔ)丁
// SDK內(nèi)部限制連續(xù)兩次queryAndLoadNewPatch()方法調(diào)用不能短于3s, 否則的話就會(huì)報(bào)code:19的錯(cuò)誤碼.
SophixManager.getInstance().queryAndLoadNewPatch();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
initHotFix();
}
private void initHotFix() {
String appVersion;
try {
appVersion = getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
appVersion = "1.0";
}
SophixManager.getInstance().setContext(this)
.setAppVersion(appVersion) //appVersion與app版本無(wú)關(guān)可以自己定義只要與自己控制臺(tái)中版本一致即可
// .setSecretMetaData(APP_ID, APP_SECRET, RSA_SECRET)
.setAesKey(null)
.setEnableDebug(true) //正式發(fā)布該參數(shù)必須為false, false會(huì)對(duì)補(bǔ)丁做簽名校驗(yàn), 否則就可能存在安全漏洞風(fēng)險(xiǎn)
.setPatchLoadStatusStub(new PatchLoadStatusListener() {
@Override
public void onLoad(final int mode, final int code, final String info, final int handlePatchVersion) {
// 補(bǔ)丁加載回調(diào)通知
Log.i("tag", "onLoad code:---------->"+code);
if (code == PatchStatus.CODE_LOAD_SUCCESS) {
// 表明補(bǔ)丁加載成功
} else if (code == PatchStatus.CODE_LOAD_RELAUNCH) {
// 表明新補(bǔ)丁生效需要重啟. 開(kāi)發(fā)者可提示用戶或者強(qiáng)制重啟;
// 建議: 用戶可以監(jiān)聽(tīng)進(jìn)入后臺(tái)事件, 然后調(diào)用killProcessSafely自殺嗦篱,以此加快應(yīng)用補(bǔ)丁冰单,詳見(jiàn)1.3.2.3
SophixManager.getInstance().killProcessSafely();//安全自殺應(yīng)用推薦
}else if (code == PatchStatus.CODE_LOAD_FAIL) {
// 內(nèi)部引擎異常, 推薦此時(shí)清空本地補(bǔ)丁, 防止失敗補(bǔ)丁重復(fù)加載
SophixManager.getInstance().cleanPatches();
} else {
// 其它錯(cuò)誤信息, 查看PatchStatus類說(shuō)明
}
}
}).initialize();
}
}
注意:上面的appVersion與app版本無(wú)關(guān)可以自己定義只要與自己控制臺(tái)中版本一致即可。
initialize的調(diào)用應(yīng)該盡可能的早灸促,必須在Application.attachBaseContext()或者Application.onCreate()的最開(kāi)始進(jìn)行SDK初始化操作诫欠,否則極有可能導(dǎo)致崩潰。而查詢服務(wù)器是否有可用補(bǔ)丁的操作可以在后面的任意地方浴栽。
5 . 混淆配置
在app目錄下的proguard-rules.pro文件下添加如下代碼:
#基線包使用荒叼,生成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
--------------------------------------到這里代碼集成已經(jīng)全部完畢-------------------------------
接下來(lái)就是如何生成這個(gè)補(bǔ)侗焕?
1萝玷、下載打補(bǔ)丁工具SophixPatchTool(Mac嫁乘、Windows、Linux)都有的球碉,以及調(diào)試工具(實(shí)際是一個(gè)apk蜓斧,記得裝到你的手機(jī)先),下載地址汁尺,就是上面這個(gè)官方生成補(bǔ)丁的文檔法精。
2、下載好了這個(gè)SophixPatchTool壓縮文件,先解壓搂蜓,按如圖操作即可
生成補(bǔ)丁的這個(gè)客戶端工具的界面是這樣的(怎么樣狼荞,很簡(jiǎn)單了吧,以前老版本都是dos命令)
- 舊包:<必填> 選擇基線包路徑(有問(wèn)題的APK)帮碰。
- 新包:<必填> 選擇新包路徑(修復(fù)過(guò)該問(wèn)題APK)相味。
- 日志:打開(kāi)日志輸出窗口。
- 高級(jí):展開(kāi)高級(jí)選項(xiàng)殉挽,
- 設(shè)置:配置其他信息丰涉。
- GO!:開(kāi)始生成補(bǔ)丁。
3 .點(diǎn)擊對(duì)話框下面的設(shè)置斯碌,會(huì)出現(xiàn)如下界面一死,簽名必須與app簽名一致 保證安全性
- 補(bǔ)丁輸出路徑:<必填> 指定生成補(bǔ)丁之后補(bǔ)丁的存放位置,必須是已存在的目錄傻唾。
- Key Store Path:<選填>本地的簽名文件的路徑投慈,不輸入則不做簽名。
- Key Store Password:<選填>證書文件的密碼冠骄。
- Key Alias:<選填>Key的別名伪煤。
- Key Passwrod:<選填>Key的密碼。
- AES Key:<選填>自定義aes秘鑰, 必須是16位數(shù)字或字母的組合凛辣。必須- 與setAesKey中設(shè)置的秘鑰一致抱既。
- Filter Class File:<選填>本地的白名單類列表文件的路徑,放進(jìn)去的類不會(huì)再計(jì)算patch扁誓,文件格式: 一行一個(gè)類名防泵。
4 . 點(diǎn)擊go 就會(huì)生成補(bǔ)丁包以.jar結(jié)尾 路徑是自己設(shè)定的
5、現(xiàn)在補(bǔ)丁已經(jīng)生成好了跋理,補(bǔ)丁需要上傳到控制臺(tái)择克。控制臺(tái)地址
這是我成功之后的截圖
發(fā)布前請(qǐng)嚴(yán)格按照:掃碼內(nèi)測(cè) => 灰度發(fā)布 => 全量發(fā)布的流程進(jìn)行,以保證補(bǔ)丁包能夠正常在所有Android版本的機(jī)型上生效前普。
6 . 下載阿里測(cè)試工具(就是一個(gè)apk哈肚邢,不是什么神秘的東西)
調(diào)試工具下載
7 . 將舊的apk和調(diào)試工具裝在手機(jī)中 打開(kāi)調(diào)試工具
輸入包名->連接應(yīng)用->掃描二維碼 觀察下方輸出的日志
如果最后結(jié)果為12,恭喜你成功了
8 . 成功的話就可以發(fā)布你的補(bǔ)丁包了拭卿,之后就可以觀察手機(jī)中舊版本的apk已經(jīng)變成新版本的了骡湖。