分享自己在項(xiàng)目中如何更好的使用阿里SopHix進(jìn)行熱修復(fù)

前言

本文最主要的是講解下自己是如何在在項(xiàng)目中更恰當(dāng)合理的運(yùn)用SopHix涛菠,當(dāng)然這只是我團(tuán)隊(duì)兩個(gè)人的做法而已。經(jīng)驗(yàn)總是要踩出來的疙渣,對(duì)同學(xué)有幫助就最好了匙奴。

以下分為六部分

  • 引言
  • 官方使用步驟
  • 測試開發(fā)中熱更新修復(fù)操作五部曲
  • 下發(fā)補(bǔ)丁步驟
  • 如何處理加載補(bǔ)丁成功后的彈窗強(qiáng)制更新提醒
  • 如何爬坑

一、引言

熱修復(fù)技術(shù)可謂是百花齊放妄荔,許多產(chǎn)品都聲稱自己可以做到全方位全功能的熱修復(fù)泼菌。不過他們各自有自身的局限性谍肤,或者不夠穩(wěn)定,或者補(bǔ)丁過大哗伯,或者效率低下荒揣,或者使用起來過于繁瑣,大部分技術(shù)上看起來似乎可行焊刹,但實(shí)際體驗(yàn)并不好系任。而在我們看來,有很多技術(shù)細(xì)節(jié)能夠做得更加完美伴澄。

終于在2017年6月11日赋除,手淘技術(shù)團(tuán)隊(duì)聯(lián)合阿里云正式發(fā)布了史上首個(gè)非侵入式移動(dòng)熱更新解決方案——Sophix。

Sophix熱修復(fù)方案主要開發(fā)者非凌,萬壑 就職于手機(jī)淘寶举农。

Sophix的橫空出世,將會(huì)打破各家熱修復(fù)技術(shù)紛爭的局面敞嗡。我們可以滿懷信心地說颁糟,在Android熱修復(fù)的三大領(lǐng)域:代碼修復(fù)、資源修復(fù)喉悴、so修復(fù)方面棱貌,以及方案的安全性和易用性方面,Sophix都做到了業(yè)界領(lǐng)先箕肃。

文章介紹 https://yq.aliyun.com/articles/103527?spm=5176.8091938.0.0.l6pz1T
??下面的這張表格引用自[ 作者博文]婚脱,從幾個(gè)熱修復(fù)最重要的維度,把Sophix和另外兩個(gè)主要商業(yè)化熱修復(fù)方案進(jìn)行了比較勺像。

Image.png

而其中唯一不支持的地方就是四大組件的修復(fù)障贸,這是因?yàn)槿绻迯?fù)四大組件,必須在AndroidManifest里面預(yù)先插入代理組件吟宦,并且盡可能聲明所有權(quán)限篮洁,而這么做就會(huì)給原先的app添加很多臃腫的代碼,對(duì)app運(yùn)行流程的侵入性很強(qiáng)殃姓≡ǎ可以插入幾個(gè)代理文件即可。我在項(xiàng)目中就這么做蜗侈。

二篷牌、官方使用步驟

Android 接入流程請(qǐng)開發(fā)者務(wù)必仔細(xì)閱讀一遍官方文檔。文檔是最好的老師
先去創(chuàng)建應(yīng)用
然后快速接入流程

三踏幻、測試開發(fā)中熱更新修復(fù)操作五部曲

  1. 打包區(qū)分的三個(gè)包
    Base_1.5.30 (基礎(chǔ)包用于對(duì)比)
    Safe_1.5.30(加固過后的包枷颊,發(fā)布給線上使用)
    Test_1.5.31(在打完Base包之后修改版本號(hào),再打一個(gè)測試包,確保代碼一致偷卧,用于安裝豺瘤,下發(fā)補(bǔ)丁首先下發(fā)到該版本,我是這么做的)

  2. Safe_1.5.30發(fā)布完上線之后 听诸,在你的Android Studio中修改版本號(hào)為1.5.33 繼續(xù)開發(fā)或者修復(fù)BUG坐求,反正需要大于1.5.31(因?yàn)槟阕鰷y試需要先在Sophix后臺(tái)下發(fā)補(bǔ)丁到1.5.31,你本地代碼沒有修改的話晌梨, build 運(yùn)行時(shí)會(huì)收到Sophix服務(wù)器的下發(fā)的補(bǔ)丁桥嗤,此時(shí)代碼覆蓋會(huì)讓你一臉懵逼)

  3. 這時(shí)你已經(jīng)在 Dev_1.5.33 版本中修復(fù)了BUG,打包1.5.33之后仔蝌,需要通過 Sophix工具上傳 基礎(chǔ)包 Base_1.5.30 進(jìn)行比對(duì)生成 Sophix-Patch.jar 補(bǔ)丁包 泛领,(生成的補(bǔ)丁與版本號(hào)無關(guān),工具只會(huì)對(duì)比代碼結(jié)構(gòu), so敛惊,資源等) 完成后將其上傳至Sophix后臺(tái)

  4. 指定下發(fā)對(duì)應(yīng)版本號(hào)渊鞋,先下發(fā)到Test_1.5.31 測試版本,補(bǔ)丁下發(fā)成功瞧挤! 手機(jī)安裝 先測試驗(yàn)收锡宋,驗(yàn)收成功之后再指定下發(fā)到 正式的版本 1.5.30 即可

  5. Tips: 在Android Studio中 開發(fā)中的版本需要比Test1.5.31版本大,便于在 Build 運(yùn)行項(xiàng)目時(shí)特恬,不會(huì)因聯(lián)網(wǎng)下發(fā)到針對(duì)1.5.31的補(bǔ)丁 指示代碼收到下發(fā)的補(bǔ)丁 受影響

注意事項(xiàng):

  • 下發(fā)補(bǔ)丁修復(fù)bug不要去修改 Manifest 的文件执俩,發(fā)布補(bǔ)丁時(shí)的版本也最好不要去修改一些依賴庫的版本,會(huì)出現(xiàn)某些問題癌刽!

  • 還有打base包的 那份代碼需要備份這個(gè)分支役首,然后copy一個(gè)分支進(jìn)行下一步的開發(fā),以防萬一合成補(bǔ)丁出錯(cuò)显拜,進(jìn)行代碼比對(duì)

  • 舊包內(nèi)部版本號(hào)不能 比新包內(nèi)部版本號(hào)大衡奥,不然會(huì)生成補(bǔ)丁出錯(cuò)

??這里我并沒有使用官方的調(diào)試工具進(jìn)行調(diào)試。而是直接在項(xiàng)目中查看日志補(bǔ)丁加載狀態(tài)讼油。要多注意每個(gè)Code代表的意思 杰赛,這里文檔也有描述到呢簸,詳情查看SDK中PatchStatus類的代碼矮台,有具體說明

四、下發(fā)補(bǔ)丁步驟

生成補(bǔ)丁工具
??假設(shè)當(dāng)前 版本為 1.5.30 為發(fā)布的包根时,而你要先進(jìn)行更新測試包更新包版本為 1.5.31 ,這個(gè)時(shí)候你就要將最新代碼生成的apk文件包與base基線版本1.5.30做比對(duì)瘦赫。此時(shí)生成的補(bǔ)丁文件 sophix-patch.jar 上傳至 Sophix 后臺(tái)。
??補(bǔ)丁版本為后臺(tái)自控的蛤迎。會(huì)進(jìn)行疊加确虱。繼續(xù)上傳一個(gè)補(bǔ)丁則上一個(gè)版本的補(bǔ)丁自動(dòng)停用.

  1. 添加版本號(hào)要注意格式1.X.X 或者 1.XXX
    ![~J$E2{$(6OFRBSI]WA7Y0MR.png](http://upload-images.jianshu.io/upload_images/956862-2a3012b0a3c770ab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  2. 上傳補(bǔ)丁文件,并且加點(diǎn)描述


    bing

官方管理后臺(tái)使用說明

五替裆、如何處理加載補(bǔ)丁成功后的彈窗強(qiáng)制更新提醒

  • 強(qiáng)制更新補(bǔ)丁狀態(tài)說明:
    一般都會(huì)把查詢補(bǔ)丁的操作放在Application中去操作校辩,Sophix啟動(dòng)APP時(shí)會(huì)調(diào)用方法請(qǐng)求查詢最新的補(bǔ)丁窘问,這句話一般在Application中的onCreate()方法的Super之前去進(jìn)行調(diào)用,這里貼一下自己項(xiàng)目中的代碼

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

public void onCreate() {
SophixManager.getInstance().queryAndLoadNewPatch();
super.onCreate();
...
}
// 阿里熱修復(fù)
private void initHotfix(Context context) {
SophixManager.getInstance().setContext(this)
.setAppVersion(VersionUtils.getVersionName(this))
.setAesKey(null)
.setEnableDebug(false)
.setPatchLoadStatusStub((mode, code, info, handlePatchVersion) -> {
// 補(bǔ)丁加載回調(diào)通知
String s = "mode:" + mode + " code:" + code + "\npatchVersion:" + handlePatchVersion + "\ninfo:" + info;
hotfixController(context, code, handlePatchVersion, s);//這里是處理相對(duì)應(yīng)的主要Code的操作宜咒,代碼就不貼完整了惠赫,你可以根據(jù)官方的來進(jìn)行操作,建議多加一個(gè)對(duì)CODE_LOAD_NOPATCH 狀態(tài)碼14故黑,沒有補(bǔ)丁的情況針對(duì)性的操作
}).initialize();
}
```

  • Q:收到Code 12 之后儿咱,有的包是需要提示用戶強(qiáng)制冷啟動(dòng)的,而有的包是不用提示场晶,等下次自己更新就好了混埠。這樣的情況怎么判斷當(dāng)前的包是處于哪種情況呢?
    需要提示 & 不需要再提示诗轻?
    A:官方給我的提示钳宪,需要自己加個(gè)推送什么的,回調(diào)中沒有這個(gè)標(biāo)識(shí)扳炬。((__) 嘻嘻…… 如果Shophix后臺(tái)有支持就好了)

  • 這里主要講解下發(fā)成功 狀態(tài)為 1 "load new patch success."時(shí)使套,也就是補(bǔ)丁下發(fā)成功了,之后提醒用戶的操作鞠柄。
    這里需要判斷兩個(gè)前提條件侦高,都要提示用戶去重啟應(yīng)用, 要注意回調(diào)狀態(tài)碼Code 等于12 “please relaunch app to load new patch” 的時(shí)候 就是冷啟動(dòng)的提示厌杜。 這里我并沒有根據(jù)12去做判斷進(jìn)行重啟奉呛。

下面說下我自己項(xiàng)目中的兩個(gè)必要重啟判斷條件,僅供參考夯尽。
     * 1瞧壮、取得SopHix SDK啟動(dòng)時(shí)返回的最新的補(bǔ)丁版本號(hào)(hotfixPatchVersion)和服務(wù)器返回的補(bǔ)丁版本號(hào)(hotfixMustUpdateVersion)相同,且大于當(dāng)前最后一次強(qiáng)制重啟的補(bǔ)丁版本號(hào)(hotfixLastMustVersion 將每次返回的補(bǔ)丁版本寫入SP記錄) 

     * 2匙握、或者第一次下載咆槽、數(shù)據(jù)被清除后,如果有新強(qiáng)制更新版本圈纺,則強(qiáng)制更新

 建議定義三個(gè)字段進(jìn)行比較
public static final String hotfixPatchVersion = "hotfixPatchVersion"; // 阿里返回的補(bǔ)丁版本號(hào)
public static final String hotfixMustUpdateVersion = "hotfixMustUpdateVersion"; // 服務(wù)器返回的版本號(hào)
public static final String hotfixLastMustVersion = "hotfixLastMustVersion"; // 最后一次強(qiáng)制重啟的版本號(hào)

注意:

  1. 以上所說的這種方式秦忿,實(shí)際項(xiàng)目中加載了最新的補(bǔ)丁,需要把這個(gè)Sophix中最新的補(bǔ)丁版本號(hào)蛾娶,告知后臺(tái)進(jìn)行修改為最新更新的補(bǔ)丁號(hào)灯谣。一般在版本更新的接口中多加入一個(gè)字段(downloadPatchCode ),請(qǐng)求時(shí)用于進(jìn)行比對(duì)蛔琅。

  2. 提示用戶關(guān)閉時(shí)的處理胎许,可以在PatchLoadStatusListener監(jiān)聽到CODE_LOAD_RELAUNCH后在合適的時(shí)機(jī),調(diào)用此方法殺死進(jìn)程。注意辜窑,不可以直接Process.killProcess(Process.myPid())來殺進(jìn)程钩述,這樣會(huì)擾亂Sophix的內(nèi)部狀態(tài)。因此如果需要?dú)⑺肋M(jìn)程穆碎,建議使用這個(gè)方法切距,它在內(nèi)部做一些適當(dāng)處理后才殺死本進(jìn)程。本人是直接在一個(gè)透明的 彈窗提示判斷中關(guān)閉時(shí)調(diào)用的此方法進(jìn)行關(guān)閉惨远。

 SophixManager.getInstance().killProcessSafely(); 

六谜悟、如何爬坑

以下是我所遇到過的兩個(gè)問題,遇到問題心態(tài)不要蹦北秽,先去查看日志葡幸,再去查看官方文檔,或者QA贺氓,百分之七八十都可以解決蔚叨,若你還不能解決你就去官方釘釘群交流:11734260 進(jìn)行交流。

問題1

熱修復(fù)Android SDK:在4.x的手機(jī)系統(tǒng)上崩潰

在4.x的系統(tǒng)上出現(xiàn)IllegalAccessException:class ref in pre-verified異常辙培,應(yīng)用崩潰

問題原因
??這個(gè)是由于我們是完整dex修復(fù)蔑水,所以會(huì)出現(xiàn)新dex中的類和老dex中的類沖突,所以要在Sophix初始化前避免加載原有apk中的類扬蕊,而對(duì)于4.x版本的系統(tǒng)搀别,如果在Sophix初始化之前有加載原有apk中的類,則會(huì)影響修復(fù)的過程尾抑,造成崩潰

解決方案
https://help.aliyun.com/knowledge_detail/55414.html?spm=5176.7851422.2.4.SyAVhp
??Sophix初始化在Application最前面歇父,同時(shí)盡量用系統(tǒng)類及盡量不使用log等,或者把initialize寫到attachBaseContext里面再愈,但query還是在onCreat的最前面榜苫;如果有用到MultiDex,直接繼承Application翎冲,在attachBaseContext里寫MultiDex.install(base)垂睬,然后在onCreat的最前面initialize和query,如果還會(huì)出現(xiàn)這個(gè)崩潰抗悍,把initialize寫到attachBaseContext的MultiDex.install(base)后面驹饺,但query還是在onCreat的最前面

問題2

這個(gè)問題很奇怪,項(xiàng)目老大解決的檐春。我現(xiàn)在只知道不能這么做而已逻淌。
??在4.X的設(shè)備上么伯,用OkHttp作為Fresco的網(wǎng)絡(luò)加載器的時(shí)候疟暖,如果發(fā)布新的包(比如只修改一個(gè)Toast),
在下載完重啟后會(huì)直接崩潰報(bào)如下錯(cuò)誤:
Process: com.newtest.myapplication, PID: java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
而其他機(jī)型則不會(huì)。 很明顯和第一個(gè)錯(cuò)誤是一樣的俐巴。

Sophix對(duì)4.X的機(jī)型有Bug: 在一個(gè)外部引用的包里骨望,自帶的實(shí)例,需要去調(diào)用這個(gè)包里的另一個(gè)實(shí)例方法時(shí)欣舵,會(huì)報(bào)上面這個(gè)錯(cuò)擎鸠; 但把這個(gè)包里的實(shí)例移到App里創(chuàng)建,再去調(diào)用相同的那個(gè)方法里就不會(huì)了缘圈。 就是說4.X的引用包里的方法不能再次調(diào)用引用包里的別的方法劣光。 現(xiàn)在已經(jīng)解決了,但5.0及以上的機(jī)型卻不會(huì)有這個(gè)Bug糟把,這只是很奇葩的問題绢涡,如果沒遇到過同學(xué)略過吧~

以上兩個(gè)問題也屬于同一個(gè)問題,詳細(xì)閱讀作者這邊文章會(huì)有些啟示遣疯。

  • 由于是直接在項(xiàng)目分支中引入的Sophix 所以沒有寫個(gè)Demo雄可。
    有空補(bǔ)上(這是我聽過過最大的笑話)
    貼一個(gè)官方Demo

以上僅是自己的處理方式,寫的不好的地方還望指正缠犀,有問題還望同學(xué)們指點(diǎn)一二数苫,O(∩_∩)O謝謝!
學(xué)會(huì)分享~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辨液,一起剝皮案震驚了整個(gè)濱河市虐急,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滔迈,老刑警劉巖戏仓,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亡鼠,居然都是意外死亡赏殃,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門间涵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仁热,“玉大人,你說我怎么就攤上這事勾哩】勾溃” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵思劳,是天一觀的道長迅矛。 經(jīng)常有香客問我,道長潜叛,這世上最難降的妖魔是什么秽褒? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任壶硅,我火速辦了婚禮,結(jié)果婚禮上销斟,老公的妹妹穿的比我還像新娘庐椒。我一直安慰自己,他們只是感情好蚂踊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布约谈。 她就那樣靜靜地躺著,像睡著了一般犁钟。 火紅的嫁衣襯著肌膚如雪棱诱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天涝动,我揣著相機(jī)與錄音军俊,去河邊找鬼。 笑死捧存,一個(gè)胖子當(dāng)著我的面吹牛粪躬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昔穴,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼镰官,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了吗货?” 一聲冷哼從身側(cè)響起泳唠,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宙搬,沒想到半個(gè)月后笨腥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勇垛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年脖母,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闲孤。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谆级,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讼积,到底是詐尸還是另有隱情肥照,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布勤众,位于F島的核電站舆绎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏们颜。R本人自食惡果不足惜吕朵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一猎醇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧边锁,春花似錦姑食、人聲如沸波岛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽则拷。三九已至贡蓖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間煌茬,已是汗流浹背斥铺。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坛善,地道東北人晾蜘。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像眠屎,于是被迫代替她去往敵國和親剔交。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容