Tinker API概覽

Tinker API概覽

我們需要使用的API大約幾種在以下幾個類中:

函數 描述
TinkerInstaller.java TinkerInstaller.java封裝了一些常用的函數,例如Tinker對象的構建,發起補丁請求以及lib庫的加載。
Tinker.java Tinker.java是Tinker庫的Manager類,tinker所有的狀態、信息都存放在這裏。
TinkerLoadResult.java TinkerLoadResult.java是用來存放加載補丁包時的相關結果,它本身也是Tinker.java的一個成員變量。
TinkerApplicationHelper.java TinkerApplicationHelper.java封裝了一些無需構建Tinker都可調用的函數,一般我們更推薦使用上面的三個類。

TinkerInstaller相關接口

TinkerInstaller封裝了一些比較重要的函數,現作簡單的說明:

Tinker實例的構建

Tinker類是整個框架的核心,我們需要構建它的單例。其中intentResult存放是我們加載補丁時的數據,它在install之後纔將數據賦值給Tinker與TinkerLoadResult類。

全部使用默認定義類的構造方法:

public static void install(ApplicationLike applicationLike) {
     Tinker.with(tinkerApplication).install(applicationLike.getTinkerResultIntent());
}

若使用了自定義類,可選擇多參數的install方法,具體用法可參考SampleApplicationLike

你一定要先install Tinker之後,才能使用Tinker相關的API。不然你只能使用TinkerApplicationHelper.java中的API。

發起補丁修復請求

正如之前所說的,補丁請求分爲修復當前版本以及升級當前版本兩種。修復當前版本一般是在當前版本的補丁文件出現缺失或不一致的情況,所有請求都將會交給PatchListener去處理。

發起修復補丁請求:

public static void onReceiveRepairPatch(Context context, String patchLocation) {
    Tinker.with(context).getPatchListener().onPatchReceived(patchLocation, false);
}

事實上,大家其實可以忽略onReceiveRepairPatch這個接口。使用者無需手動調用,在DefaultLoadReporter中的onLoadFileNotFound會自動調用。它的作用是自動恢復已經加載補丁的缺失文件。

發起升級補丁請求,即收到一個新的補丁包,多次補丁也是調用下面這個接口:

public static void onReceiveUpgradePatch(Context context, String patchLocation) {
    Tinker.with(context).getPatchListener().onPatchReceived(patchLocation, true);
}

Library庫的加載

更新的Library庫文件我們幫你保存在tinker下面的子目錄下,但是我們並沒有爲你區分abi(部分手機判斷不準確)。所以若想加載最新的庫,你有兩種方法,第一個是直接嘗試去Tinker更新的庫文件中加載,第二個參數是庫文件相對安裝包的路徑。

TinkerInstaller.loadLibraryFromTinker(getApplicationContext(), "assets/x86", "libstlport_shared");

但是我們更推薦的是,使用TinkerInstaller.loadLibrary接管你所有的庫加載,它會自動先嚐試去Tinker中的庫文件中加載,但是需要注意的是當前這種方法只支持lib/armeabi目錄下的庫文件

//load lib/armeabi library
TinkerInstaller.loadArmLibrary(getApplicationContext(), "libstlport_shared");
//load lib/armeabi-v7a library
TinkerInstaller.loadArmV7Library(getApplicationContext(), "libstlport_shared");

若存在Tinker還沒install之前調用加載補丁中的Library庫,可使用TinkerApplicationHelper.java的接口

//load lib/armeabi library
TinkerApplicationHelper.loadArmLibrary(tinkerApplicationLike, "libstlport_shared");
//load lib/armeabi-v7a library
TinkerApplicationHelper.loadArmV7Library(tinkerApplicationLike, "libstlport_shared");

若想對第三方代碼的庫文件更新,可先使用TinkerInstaller.load*Library對第三方庫做提前的加載!更多使用方法可參考MainActivity.java

當前使用方式似乎並不能做到開發者透明,這是因爲我們想盡量少的去hook系統框架減少兼容性的問題。這邊歡迎大家一起討論是否可以採用更加激進的策略,大家在正式發佈前都應該測試補丁的Library是否真正的生效。

設置LogIml實現

你可以設置自己的Log輸出實現:

public static void setLogIml(TinkerLog.LogImp imp) {
    TinkerLog.setLogImp(imp);
}

Tinker類相關接口

Tinker類是整個庫的核心,基本所有的補丁相關的信息我們都可以在這裏獲取到。TinkerApplication也有一些獲取tinkerFlag的相關API,它們可以在Tinker未被初始化前使用。

獲取單例的方法

獲取單例的方法非常簡單:

Tinker manager = Tinker.with(context);

獲取加載狀態

loaded成員變量是標記是否有補丁加載成功的標記,只有它爲true時,才能保證TinkerLoadResult的各個變量非空。

boolean isLoaded = Tinker.with(context).isTinkerLoaded();
boolean isInstalled = Tinker.with(context).isTinkerInstalled();

獲得加載的結果,也就是TinkerLoadResult的實例。它是有可能爲空的,使用它請先確保loaded爲true:

TinkerLoadResult loadResult = Tinker.with(context).getTinkerLoadResultIfPresent();

清除補丁

當補丁出現異常或者某些情況,我們可能希望清空全部補丁,調用方法爲:

Tinker.with(context).cleanPatch();

當然我們也可以選擇卸載某個版本的補丁文件:

Tinker.with(context).cleanPatchByVersion();

在升級版本時我們也無須手動去清除補丁,框架已經爲我們做了這件事情。需要注意的是,在補丁已經加載的前提下清除補丁,可能會引起crash。這個時候更好重啓一下所有的進程。

其他API這裏不再一一概述,請大家自行翻閱Tinker.java

TinkerLoadResult相關接口

因爲加載補丁是在Tinker的Install之前的,我們將加載的結果保存在intent中,然後在Tinker的install方法中恢復這些結果。這裏包括補丁的所有信息,例如加載的dex,library,我們定義的package config以及各個文件的目錄等。但是需要注意的是,這裏面的變量大多數是nullable。若Tinker的loaded爲true,除了dexes與libs(要看補丁包裏面是否真的有),其他變量可以確保非空。

獲取packageConfig:

public String getPackageConfigByName(String name) {
    if (packageConfig != null) {
        return packageConfig.get(name);
    }
    return null;
}

這裏需要注意的是,檢查dex的Md5值需要使用SharePatchFileUtil.verifyDexFileMd5方法,這是由於dex有可能是被我們重新打包成jar模式。

//獲得基準包的tinkerId
String oldTinkerId = Tinker.with(context).getTinkerLoadResultIfPresent().getTinkerID();
//獲得補丁包的tinkerId
String newTinkerId = Tinker.with(context).getTinkerLoadResultIfPresent().getNewTinkerID();

更多接口請參考TinkerLoadResult.java

TinkeApplicationHelp相關接口

在有些時候,你可能想在更後的時機纔去installTinker,甚至在某些進程永遠也不會去做這個動作。那樣你可以通過TinkerApplicationHelper.java來獲得一些當前加載的信息。

基本所有的信息都可以在這裏獲得,但是由於這裏是直接讀取結果intent

還有其他問題?請參考Tinker 常見問題!

發佈了34 篇原創文章 · 獲贊 78 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章