课程名称:BAT大牛亲授技能+技巧 Android面试快速充电升级
课程章节:Android基础相关面试问题
主讲老师:DocMike
课程内容
Android 插件化最早是为了解决方法数超过 65535(64K) 的问题,使用插件化能够减少安装 Apk 的体积,用户可以按照需要下载插件,还可以动态更新插件。插件化中涉及到的知识点是面试中会被问到的问题。
1.Android 的类加载机制
类加载器 ClassLoader 是 JVM 平台提供的类加载器,它允许程序从网络、磁盘甚至内存中加载 class,这就为 Android 的插件化提供了技术基础。ClassLoader 并不会一次把所有 Java 类加载到内存中,而是在应用程序需要的时候加载。在插件化中主要用到的两个类加载器是 DexClassLoader 和 PathClassLoader。
DexClassLoader 和 PathClassLoader,它们都继承于 BaseDexClassLoader。DexClassLoader 多传了一个optimizedDirectory 参数,这个目录必须是内部存储路径,用来缓存系统创建的 Dex 文件。而 PathClassLoader该参数为 null,只能加载内部存储目录的 Dex 文件。Android 对于外部的 dex 文件,主要通过 DexClassLoader 类加载。
2.Android 的资源加载机制
Android 应用的开发其实崇尚的是逻辑与资源分离的理念,所有资源(layout、values 等)都会被打包到 Apk 中,然后生成一个对应的 R 类,其中包含对所有资源的引用 id。Android 系统通过 Resource 对象加载资源。因此,只要将插件 apk 的路径加入到 AssetManager 中,便能够实现对插件资源的访问。由于 AssetManager 并不是一个public 的类,需要通过反射去创建。各个插件的资源是互相隔离的,如果想要实现资源的共享,必须拿到对应的Resource 对象。
3.反射和动态代理
Android 中的四大组件,是由系统创建的,并且由系统管理生命周期。由于插件 apk 的四大组件无法在宿主中注册,需要使用反射和动态代理的方法绕过 AMS。可以在主工程中放一个 ProxyActivy,启动插件中的 Activity 时会先启动ProxyActivity,在 ProxyActivity 中创建插件 Activity,并同步生命周期。
所有插件的启动需要通过统一的入口来启动插件 Activity,其内部会将启动的插件 Activity 信息保存下来,并将intent 替换为启动 ProxyActivity 的 intent。ProxyActivity 根据插件的信息拿到该插件的 ClassLoader 和 Resource,通过反射创建 PluginActivity 并调用其 onCreate() 方法。
PluginActivty 调用的 setContentView() 被重写了,会去调用 ProxyActivty 的 setContentView()。由于ProxyActivity 重写了 getResource() 返回的是插件的 Resource,所以 setContentView() 能够访问到插件中的资源。同样 findViewById() 也是调用 ProxyActivity 的。
课程收获
这一章从 Android 插件化应用到的技术点的角度来分析插件化框架,有时候当我们在使用框架时,不只要关注框架的工具属性,还要去挖掘其底层的原理,才能让自己的技术得到提升。