昨天一不小心搞出一个bug,而且还是崩溃,但是很快我就找到了原因,并且修复了bug提交了代码,一会儿qa马上热发了一版,这样我的崩溃问题就解决了,这也太快了!Android更新不是要先发应用市场,然后等待好几周的审核,然后有的用户还不肯更新吗?这里面到底用到了什么黑科技?于是我想知道android热发的原理,开始查android热发,没有找到什么有价值的东西,后来搜android 组件化开发,在知乎上找到一篇,回答很简单,但是有一个链接到他详细博客的地址http://www.trinea.cn/android/android-plugin/ ,根据博客里面提供的信息,我了解了几个开源框架是如何实现热加载,或者说是热发的。
热发的过程:
- apk插件更新:通过差分(bsdiff),来更新需要更新的apk插件,最小化用户的下载量。
- 宿主程序动态加载更新之后的apk插件,完成热发。
组件开发的概念:
宿主程序通过ClassLoader去动态加载apk文件并将其放在自己的进程中执行。
基本概念理解资料:
- ClassLoader:
http://www.trinea.cn/android/java-loader-common-class/
http://android-developers.blogspot.hk/2011/07/custom-class-loading-in-dalvik.html (进阶) - AndroidApk动态加载机制
http://blog.csdn.net/singwhatiwanna/article/details/22597587
http://blog.csdn.net/singwhatiwanna/article/details/23387079 - 开源项目dl的介绍:
http://blog.csdn.net/singwhatiwanna/article/details/39937639
组件开发的好处:
- 动态更新。不用频繁卸载安装apk程序。
- 可以多个项目同时开发,减少apk的大小,并且每个项目可以同时进行,减少编译时间等等。
组件开发需要解决的问题:
https://github.com/singwhatiwanna/dynamic-load-apk 这个很好地解释了为什么会有这两个问题
Activity生命周期的管理。
apk被宿主程序调起以后,apk中的activity其实就是一个普通的对象,不具有activity的性质 ,因为系统启动activity是要做很多初始化工作的,而我们在应用层通过反射去启动activity是很难完成系统所做的初始化工作的,所以activity的大部分特性都无法使用包括activity的生命周期管理,这就需要我们自己去管理。
资源的访问。
我们知道,宿主程序调起未安装的apk,一个很大的问题就是资源如何访问,具体来说就是,凡是以R开头的资源都不能访问了,因为宿主程序中并没有apk中的资源,所以通过R来加载资源是行不通的,程序会报错:无法找到某某id所对应的资源。
几种动态加载开源项目的实现:
原文链接:http://www.trinea.cn/android/android-plugin/
DynamicLoadApk
GitHub:https://github.com/singwhatiwanna/dynamic-load-apk
这个项目实现了一部分的动态加载,原理是 DexClassLoader 加 Activity 代理,可以看看。即在容器中注册几个代理的 Activity,启动插件的 Activity 时实际启动的都是代理的 Activity,这样就解决了 Activity 必须注册的问题。
当然这个项目里也有不少问题没解决,有兴趣可以加入他们。AndroidDynamicLoader GitHub:https://github.com/mmin18/AndroidDynamicLoader
这是点评一个工程师介绍的方式,和上面不同的是:他不是用代理 Activity 的方式实现而是用 Fragment 以及 schema 的方式实现Android PluginManager GitHub:https://github.com/houkx/android-pluginmgr
这个项目的原理实际也是 DexClassLoader 加 Activity 代理,不同的是上面的 dynamic-load-apk 项目中,插件需要依赖框架的 lib,插件组件继承框架 lib 的 Base 组件。而这个框架通过字节码操作动态生成一个子类去继承插件组件解决插件必须依赖框架的问题,从而达到插件无需做任何改动(理论上)即可加载的效果。
最近的:
淘宝的 Atlas现在更名为ACDD
https://github.com/bunnyblue/ACDD
https://github.com/bunnyblue/ACDDExtension360 的 DroidPlugin
https://github.com/Qihoo360/DroidPlugin