Android 插件化技術窺探

在Android 插件化技術中(宿主app和插件app設置相同的sharedUserId),動態加載apk有兩種方式:app

  • 一種是將資源主題包的apk安裝到手機上再讀取apk內的資源,這種方式的原理是將宿主app和插件app設置相同的sharedUserId,這樣兩個app將會在同一個進程中運行,並能夠相互訪問內部資源了。
  • 一種是不用安裝資源apk的方式。其原理是經過DexClassLoader類加載器去加載指定路徑下的apk、dex或者jar文件,反射出R類中相應的內部類而後根據資源名來獲取咱們須要的資源id,而後根據資源id獲得對應的圖片或者xml文件。

下面介紹幾種常見的方法獲取資源以及代碼的方法。函數

  • 獲取已安裝的APK中的資源
    利用Context的createPackageContext方法,能夠建立另一個包的上下文,裏面有兩個參數packageName包名,flags 標誌位(CONTEXT_INCLUDE_CODE、CONTEXT_IGNORE_SECURITY)
    用法以下
try {  
    context = createPackageContext("com.test.resource", 
                                   Context.CONTEXT_INCLUDE_CODE  
                                  | Context.CONTEXT_IGNORE_SECURITY);  
    textView.setText(context.getResources().getText(R.string.message));  
} catch (NameNotFoundException e) {  
   e.printStackTrace();  
}  
  • 獲取未安裝的APK中的資源

新建一個獲取資源的接口,傳入插件APK的路徑返回Resources對象佈局

// 獲取插件apk的Resources對象
public Resources getBundleResource(Context context, String apkPath) {
    AssetManager assetManager = createAssetManager(apkPath);
    return new Resources(assetManager, 
                         context.getResources().getDisplayMetrics(), 
                         context.getResources().getConfiguration());
}

private AssetManager createAssetManager(String apkPath) {
    try {
        AssetManager assetManager = AssetManager.class.newInstance();
        AssetManager.class.getDeclaredMethod("addAssetPath", String.class)
                          .invoke(assetManager, apkPath);
        return assetManager;
    } catch (Throwable th) {
        th.printStackTrace();
    }
    return null;
}

得到了Resource 對象以後,就能夠經過函數resources.getDrawable、resources.getString、resources.getLayout 獲取圖片、字符串、佈局文件了。spa

相關文章
相關標籤/搜索