在研究dexposed時候,怎麼使用另外一個apk的資源。
我們知道,activity的工作主要是由ContextImpl來完成的, 它在activity中是一個叫做mBase的成員變量。注意到Context中有如下兩個抽象方法,看起來是和資源有關的,實際上context就是通過它們來獲取資源的,這兩個抽象方法的真正實現在ContextImpl中。也即是說,只要我們自己實現這兩個方法,就可以解決資源問題了。
/** Return an AssetManager instance for your application's package. */
public abstract AssetManager getAssets();
/** Return a Resources instance for your application's package. */
public abstract Resources getResources();
以下是我的實現方式:
首先需要把新的包資源添加到宿主包中:
/**
* 添加 新的 apk文件資源 到宿主apk文件中
*
* @param dexPath 新的apk文件
* @return 資源管理
*/
public static AssetManager createAssetManager(String dexPath) {
try {
AssetManager assetManager = AssetManager.class.newInstance();
// 反射添加新的dex包的
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, dexPath);
return assetManager;
} catch (Exception e) {
return null;
}
}
然後把資源路徑放入資源中 /**
* 創建 新的資源resources 添加
*
* @param activity 上下文
* @param assetManager 資源路徑管理
* @return 新的資源(包含 新加包,宿主包)
*/
public static Resources createResources(Activity activity, AssetManager assetManager) {
Resources superRes = activity.getResources();
Resources resources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
return resources;
}
這樣我們就獲取到了新的 Resources 資源了,我們就可以使用新的資源加載patch 包中的資源了。