Android插件化开发 第二篇 [动态加载apk优化]

引言

上篇文章我们有提到过ClassLoader类加载器,通过学习了解到系统提供的类加载器有 PathClassLoader DexClassLoader两种。它们的不同之处是:

  • PathClassLoader只能加载系统/data/data/包名目录下的apk;
  • DexClassLoader可以加载jar/apk/dex,可以从SD卡中加载的apk;

当Android应用开启的时候会创建一个PathClassLoader用来加载自己apk中的类,上篇文章中我们使用的installBundleDexs方法也就是将插件化apk的类加载到App的PathClassLoader中。文章末尾提到过两个问题:

  1. Dex加载与系统版本密切相关,可能导致新版本系统无法加载。
  2. 到当插件化apk体积的增大,方法数的增多势必导致加载漫长。网上的一种观点认为当同一个ClassLoader中的方法数增多,会导致findClass时间变长,从而影响到查找速度。

本篇通过使用DexClassLoader来优化这两个问题。

Demo创建

修改AssetsDexLoader.java中的加载方法为:

private static List<DexClassLoader> bundleDexClassLoaderList = new ArrayList<DexClassLoader>();
private static void installBundleDexs(ClassLoader loader, File dexDir, List<File> files) {
    if (!files.isEmpty()) {
        for (File f : files) {
            DexClassLoader bundleDexClassLoader = new DexClassLoader(
                    f.getAbsolutePath(), dexDir.getAbsolutePath(), null,                    loader);
            bundleDexClassLoaderList.add(bundleDexClassLoader);
        }
    }
}

新增Class获取方法:

public static Class<?> loadClass(String className) throws ClassNotFoundException {
    try {
        Class<?> clazz = Class.forName(className);
        if (clazz != null) {
            System.out.println("debug: class find in main classLoader");
            return clazz;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    for (DexClassLoader bundleDexClassLoader : bundleDexClassLoaderList) {
        try {
            Class<?> clazz = bundleDexClassLoader.loadClass(className);
            if (clazz != null) {
                System.out.println("debug: class find in bundle classLoader");
                return clazz;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    throw new ClassCastException(className + " not found exception");
}

[Demo可参考这里]

讲解

用插件化apk直接创建系统的DexClassLoader,反射调用的时候先检查PathClassLoader中是否存在,如果不存在就在DexClassLoader list中查找。

总结

使用DexClassLoader代替PathClassLoader除了可以解决Dex加载与系统版本密切问题之外,还可以将第三方apk复制到外置SD卡上减少应用安装后的体积。至于网上流传的观点拆分ClassLoader能提高findClass效率并不知道是否真实。不过总的来说用DexClassLoader代替PathClassLoader确实更为妥当。

所以轻量级插件化开发更适合使用DexClassLoader来实现。

下一篇我们会学习插件化开发如何共享使用资源。



文/H3c(简书作者)
原文链接:http://www.jianshu.com/p/900f763e99fa
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值