熱修復(fù)框架 - Tinker disable邏輯梳理

代碼基于tinker 1.9.14.7

一队询、tinker disable方式:

Tinker.with(context).setTinkerDisable();//內(nèi)存保存flag唆铐,禁止當(dāng)前進(jìn)程重復(fù)觸發(fā)tinker熱修復(fù)。

ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context)//sp持久化,禁止當(dāng)前安裝應(yīng)用重復(fù)觸發(fā)tinker熱修復(fù)。

二、tinker disable場景:

2.1 Tinker.with(context).setTinkerDisable()
加載異常

DefaultLoadReporter.onLoadException 
TinkerLoadResult.parseTinkerResult{
...
//found uncaught exception, just return
Throwable exception = ShareIntentUtil.getIntentPatchException(intentResult);
if (exception != null) {
  ...
    tinker.getLoadReporter().onLoadException(exception, errorCode);
    return false;
}
...
}

合成異常

DefaultPatchReporter.onPatchException  
TinkerPatchService.doApplyPatch{
...
try {
    if (upgradePatchProcessor == null) {
        throw new TinkerRuntimeException("upgradePatchProcessor is null.");
    }
    result = upgradePatchProcessor.tryPatch(context, path, patchResult);
} catch (Throwable throwable) {
    e = throwable;
    result = false;
    tinker.getPatchReporter().onPatchException(patchFile, e);
}

...
}

2.2 ShareTinkerInternals.setTinkerDisableWithSharedPreferences

DefaultLoadReporter onLoadException {

  switch (errorCode) {
     case ShareConstants.ERROR_LOAD_EXCEPTION_DEX: load dex失敗
       ...
        ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context);
        break;
    case ShareConstants.ERROR_LOAD_EXCEPTION_RESOURCE: load res失敗
       ...
        ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context);
        break;
    case ShareConstants.ERROR_LOAD_EXCEPTION_UNCAUGHT: 安全模式進(jìn)入3次
       ...
        ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context);
       ...
        break;
    case ShareConstants.ERROR_LOAD_EXCEPTION_UNKNOWN:反射獲取tinker loader失敗
       無任何邏輯
        break;
    default:
        break;
   }
...
}

三别伏、tinker disable邏輯分析

Tinker.with(context).setTinkerDisable()覆蓋patch合成和加載兩個場景,本次熱修復(fù)不再重復(fù)忧额,但是下次重啟app又會觸發(fā)熱修復(fù)(前提是tinkerFlags 不為 TINKER_DISABLE)厘肮。

ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context)覆蓋patch加載場景,針對加載dex睦番、res以及安全模式驗證這三處非客戶端邏輯部分类茂。此處觸發(fā)的加載失敗一般與系統(tǒng)相關(guān),因此tinker在此處無差別進(jìn)行了持久化級別的disable托嚣。

四巩检、案例

這里主要分析下ShareTinkerInternals.setTinkerDisableWithSharedPreferences(context)場景:
基于tinker 1.9.6的錯誤日志:

2020-09-16 18:24:51.361 8791-8791/? E/Tinker.ResourceLoader: resource hook check failed.
java.lang.NoSuchFieldException: Field mStringBlocks not found in class android.content.res.AssetManager
at com.tencent.tinker.loader.shareutil.ShareReflectUtil.findField(ShareReflectUtil.java:55)
at com.tencent.tinker.loader.TinkerResourcePatcher.a(TinkerResourcePatcher.java:101)
at com.tencent.tinker.loader.TinkerResourceLoader.checkComplete(TinkerResourceLoader.java:122)
at com.tencent.tinker.loader.TinkerLoader.tryLoadPatchFilesInternal(TinkerLoader.java:216)
at com.tencent.tinker.loader.TinkerLoader.tryLoad(TinkerLoader.java:58)
at java.lang.reflect.Method.invoke(Native Method)
at com.tencent.tinker.loader.app.TinkerApplication.loadTinker(TinkerApplication.java:163)
at com.tencent.tinker.loader.app.TinkerApplication.onBaseContextAttached(TinkerApplication.java:132)
at com.tencent.tinker.loader.app.TinkerApplication.attachBaseContext(TinkerApplication.java:148)

這里TinkerResourceLoader.checkComplete 之后走的邏輯是:

try {
    TinkerResourcePatcher.isResourceCanPatch(context);
} catch (Throwable e) {
    Log.e(TAG, "resource hook check failed.", e);
    intentResult.putExtra(ShareIntentUtil.INTENT_PATCH_EXCEPTION, e);
    ShareIntentUtil.setIntentReturnCode(intentResult, ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_LOAD_EXCEPTION);//返回res加載失敗exception,設(shè)置sp為false
    return false;
}

報錯點(diǎn)在TinkerResourcePatcher.isResourceCanPatch(context);

Tinker 1.9.6:

public static void isResourceCanPatch(Context context) throws Throwable {
  ...
    // Kitkat needs this method call, Lollipop doesn't. However, it doesn't seem to cause any harm
    // in L, so we do it unconditionally.
    stringBlocksField = findField(assets, "mStringBlocks");
    ensureStringBlocksMethod = findMethod(assets, "ensureStringBlocks");
    ...
}

Tinker 1.9.14.7:

public static void isResourceCanPatch(Context context) throws Throwable {
    ...
    // Kitkat needs this method call, Lollipop doesn't. However, it doesn't seem to cause any harm
    // in L, so we do it unconditionally.
    try {
        stringBlocksField = findField(assets, "mStringBlocks");
        ensureStringBlocksMethod = findMethod(assets, "ensureStringBlocks");
    } catch (Throwable ignored) {
        // Ignored.
    }
   ...
}

1.9.6 反射android.content.res.AssetManager獲取mStringBlocks屬性找不到示启,也沒try catch兢哭,直接拋異常。1.9.14.7進(jìn)行了try catch...

因為tinker做了大量的源碼hook夫嗓,容易出現(xiàn)異常迟螺,對這類問題tinker統(tǒng)一通過sp設(shè)置開關(guān)來無差別關(guān)閉熱修復(fù)功能。但是這也會導(dǎo)致一個問題舍咖,就是例如res加載失敗也會影響后續(xù)僅修改了dex的patch包的修復(fù)矩父。
因此這里建議對包進(jìn)行區(qū)分,如果有新的修復(fù)包排霉,還是打開開關(guān)浙垫,嘗試做修復(fù),僅對相同修復(fù)失敗的包進(jìn)行禁止郑诺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載夹姥,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末辙诞,一起剝皮案震驚了整個濱河市辙售,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌飞涂,老刑警劉巖旦部,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祈搜,死亡現(xiàn)場離奇詭異,居然都是意外死亡士八,警方通過查閱死者的電腦和手機(jī)容燕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來婚度,“玉大人蘸秘,你說我怎么就攤上這事』茸拢” “怎么了醋虏?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哮翘。 經(jīng)常有香客問我颈嚼,道長,這世上最難降的妖魔是什么饭寺? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任阻课,我火速辦了婚禮,結(jié)果婚禮上艰匙,老公的妹妹穿的比我還像新娘限煞。我一直安慰自己,他們只是感情好旬薯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布晰骑。 她就那樣靜靜地躺著,像睡著了一般绊序。 火紅的嫁衣襯著肌膚如雪硕舆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天骤公,我揣著相機(jī)與錄音抚官,去河邊找鬼。 笑死阶捆,一個胖子當(dāng)著我的面吹牛凌节,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播洒试,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼倍奢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了垒棋?” 一聲冷哼從身側(cè)響起卒煞,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叼架,沒想到半個月后畔裕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衣撬,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年扮饶,在試婚紗的時候發(fā)現(xiàn)自己被綠了具练。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡甜无,死狀恐怖扛点,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毫蚓,我是刑警寧澤占键,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布昔善,位于F島的核電站元潘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏君仆。R本人自食惡果不足惜翩概,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望返咱。 院中可真熱鬧钥庇,春花似錦、人聲如沸咖摹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萤晴。三九已至吐句,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間店读,已是汗流浹背嗦枢。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屯断,地道東北人文虏。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像殖演,于是被迫代替她去往敵國和親氧秘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

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