友情跳轉:基於DexClassLoader類裝載器開發plugin插件
/** * 根據plugin插件路徑創建插件AssetManager對象 * * @param apkPath * @return */ private AssetManager createPluginAssetManager(String apkPath) { try { AssetManager assetManager = AssetManager.class.newInstance(); try { AssetManager.class.getDeclaredMethod("addAssetPath", String.class).invoke( assetManager, apkPath); } catch (Throwable th) { System.out.println("debug:createAssetManager :"+th.getMessage()); th.printStackTrace(); } return assetManager; } catch (Throwable th) { System.out.println("debug:createAssetManager :"+th.getMessage()); th.printStackTrace(); } return null; } /** * 使用反射的方式,使用Plugin的Resource對象,替換Context的mResources對象 * * @param context * @param resources */ public void replaceContextResources(Context context, Resources resources){ try { Field field = context.getClass().getDeclaredField("mResources"); field.setAccessible(true); field.set(context, resources); System.out.println("debug:repalceResources succ"); } catch (Exception e) { System.out.println("debug:repalceResources error"); e.printStackTrace(); } } /** * 獲取plugin插件中的Resources資源對象 * * @param context * @param apkPath * @return */ public Resources getPluginResource(Context context, String apkPath){ AssetManager assetManager = createPluginAssetManager(apkPath); return new Resources(assetManager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration());
}