动态加载技术(也叫插件化技术)在技术驱动型的公司相当重要。通过插件化来减轻应用的内存和CPU占用,还可以实现热插拔(即在不发布新版本的情况下更新某些模块)。
宿主是指普通的apk,而插件一般是指经过处理的dex或者apk,在主流的插件化框架中多采用经过特殊处理的apk来作为插件,处理的方式往往和编译以及打包环节有关。另外很多插件化矿建都需要用到代理Activity的概念,插件Activity的启动大多数是借助一个代理Activity来实现的。
插件化方案的三个基础问题:
1、资源访问
宿主程序调起未安装的插件apk,一个很大的问题及时资源如何访问,具体来说就是插件中凡是以R开头的资源都不能访问了。因为宿主程序中并没有插件的资源,所以通过R来加载插件的资源是行不通的。
Activity的工作主要是通过ContextImpl来完成的,Activity中有一个叫mBase的成员变量,它的类型就是ContextImpl。注意到Context中有两个抽象方法,Context就是通过他们来获取资源的。
public abstract AssetMannager getAsset();
public abstract Resources getResources();
通过反射去加载插件的资源,详见Android开发艺术
protected void loadResources() {
try {
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, mDexPath);
mAssetManager = assetManager;
}catch (InstantiationException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
}catch (NoSuchMethodException e) {
e.printStackTrace();
}
Resources superRes =super.getResources();
mResources =new Resources(mAssetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
mTheme =mResources.newTheme();
mTheme.setTo(super.getTheme);
}
接着在代理Activity中实现getAssets()和getResources()。
3、插件ClassLoader的管理
详见Android开发艺术探索P468。