DynamicLoadApk 应该算是 Android 插件化诸多框架中资历比较老的一个了。它的项目地址在:dynamic-load-apk。该项目运行之后的效果是,使用 Gradle 编译出插件包和宿主包,都是以 APK 的形式。安装宿主包之后,通过 ADB 将插件包 push 到手机中。启动宿主包时,它会自动进行扫描将插件加载到应用中。点击插件之后,进入到插件的应用界面。
印象中最初接触的插件都是以单独安装的形式存在的,比如我可以做一个基础的应用,然后在该应用的基础上开发插件。用户可以对插件进行选择,然后下载并安装,以让自己的应用具有更丰富的功能。插件化也算是一种比较实用的技术,毕竟我们使用 Chrome 和 AS 的时候不是一样要加载插件。只是比较反感的是去修改底层的代码,容易给系统带来不稳定因素不说,技术到了一些人手里,你知道他用来干什么。插件化挺好,但真的要去推广这项技术,还是看好 Google 官方去进行规范。
技术要服务于产品,好的产品不一定要高超的技术,技术并不是最重要的,重要的是你究竟想要表达什么。这就像国内很多人只注重数理化,不注重人文学科。相比于国内的技术精英,我还是比较赞同 Google 站在整个生态的角度去考虑技术演进。前些日子社区里对插件化的讨论:移动开发的罗曼蒂克消亡史。好吧,我自己的理解是,这从来就不是什么罗曼蒂克。
DynamicLoadApk 插件化的实现方式还是挺有意思的,它使用纯 Java 实现,没有涉及 Native 层的代码,下面我理了下 DynamicLoadApk 的 Demo 程序的整个执行过程。后续的文章我们就围绕这张图进行,
首先是扫描文件路径并加载 APK,这里需要解析 APK 文件的信息,它是本质上是通过 PMS 实现的;
public DLPluginPackage loadApk(final String dexPath, boolean hasSoLib) {
mFrom = DLConstants.FROM_EXTERNAL;
// 通过 PMS 获取包信息,这里获取了 Activity 和 Service 的信息
PackageInfo packageInfo = mContext.getPackageManager().getPackageArchiveInfo(dexPath,
PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
if (packageInfo == null) {
return null;
}
DLPluginPackage pluginPackage = preparePluginEnv(packageInfo, dexPath);
if (hasSoLib) {
copySoLib(dexPath);
}
return pluginPackage;
}
然后,它通过调用 preparePluginEnv() 方法来创建 AssetManager, DexClassLoader 和 Resource 等。我们的插件类加载各种资源和类的时候使用的就是这哥仨:
private DLPluginPackage preparePluginEnv(PackageInfo packageInfo, String dexPath) {
DLPluginPackage pluginPackage = mPackagesHolder.get(packageInfo.packageName);
if (pluginPackage != null) {
return pluginPackage;
}
DexClassLoader dexClassLoader = createDexClassLoader(dexPath);
AssetManager assetManager = createAssetManager(dexPath);
Resources resources = createResources(assetManager);
// create pluginPackage
pluginPackage = new DLPluginPackage(dexClassLoader, resources, packageInfo);
mPackagesHolder.put(packageInfo.packageName, pluginPackage);
return pluginPackage;
}
private DexClassLoader createDexClassLoader(String dexPath) {

本文详细分析了DynamicLoadApk插件化框架的工作原理,包括扫描加载APK、创建AssetManager、DexClassLoader和Resource,以及启动插件Activity的过程。通过代理Activity和DLBasePluginActivity,实现了插件类的生命周期管理,避免了AMS的直接调度。
最低0.47元/天 解锁文章
842

被折叠的 条评论
为什么被折叠?



