插件化
App 的部分功能模块在打包时并不以传统方式打包进 apk 文件中,而是以另⼀种形式⼆次封装进 apk内部,或者放在网络上适时下载,在需要的时候动态对这些功能模块进行加载,称之为插件化。这些单独⼆次封装的功能模块 apk ,就称作「插件」,初始安装的 apk 称作「宿主」。
插件化步骤:
主Apk分析:
- 主App打包完成后,会形成dex,image,xml资源
- Dex靠PathClassLoader加载
- 图片以及xml资源靠Resource加载
代码实现:
- 创建DexClassLoader加载插件代码
- 创建Resource加载资源文件
- 管理插件Activity生命周期
插件化基础:反射
- 使用反射的目的:
Java 既然提供了可见性关键字 public private 等等,用来限制代码之间的可见性。可见性特性的支持不是为了代码不被坏⼈使用,而是是为了程序开发的简洁性。可见性的支持提供的是 Safety 的安全,而不是 Security 的安全。即,可见性的支持让程序更不容易写出 bug,而不是更不容易被人入侵。反射的支持可以让开发者在可见性的例外场景中,可以突破可见性限制来调⽤自己需要的 API。这是基于对开发者「在使⽤反射时已经足够了解和谨慎」的假设的。所以,可见性的支持不是为了防御外来者⼊侵,因此反射功能的⽀持并没有什么不合理。
总结一句话:反射可以让程序员抛开代码的限制,任意使用各种方法。
try {
Class clz = Class.forName("com.king.reflect.Apple");
Constructor constructor = clz.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Object object = constructor.newInstance();
Method method = clz.getDeclaredMethod("setPrice", int.class);
method.setAccessible(true);
method.invoke(object, 4);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
插件化原理:动态加载
通过自定义 ClassLoader 来加载新的 dex 文件,从而让程序员原本没有的类可以被使用,这就是插件化的原理。
- 关于 DEX:
class: java编译后的文件,每个类对应⼀个class文件
dex: Dalvik EXecutable 把class打包在⼀起,⼀个dex可以包含多个class文件
File dexfile = new File(getCacheD