Android 插件化技術(shù)窺探
在Android 插件化技術(shù)中(宿主app和插件app設(shè)置相同的sharedUserId),動態(tài)加載apk有兩種方式:
- 一種是將資源主題包的apk安裝到手機上再讀取apk內(nèi)的資源,這種方式的原理是將宿主app和插件app設(shè)置相同的sharedUserId,這樣兩個app將會在同一個進程中運行,并可以相互訪問內(nèi)部資源了。
- 一種是不用安裝資源apk的方式。其原理是通過DexClassLoader類加載器去加載指定路徑下的apk、dex或者jar文件,反射出R類中相應(yīng)的內(nèi)部類然后根據(jù)資源名來獲取我們需要的資源id,然后根據(jù)資源id得到對應(yīng)的圖片或者xml文件。
下面介紹幾種常見的方法獲取資源以及代碼的方法。
- 獲取已安裝的APK中的資源
利用Context的createPackageContext方法,可以創(chuàng)建另外一個包的上下文,里面有兩個參數(shù)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 對象之后,就可以通過函數(shù)resources.getDrawable、resources.getString、resources.getLayout 獲取圖片、字符串、布局文件了。
- 獲取插件APK的代碼
參考博客Android 熱修復(fù)原理解析
浙公網(wǎng)安備 33010602011771號