转载自http://www.chopiter.com/android_plugin/
本文旨在梳理Android插件化的历史及对比各家技术能解决的问题,对比出优缺点。既是Android插件化的总结,又可以当做插件化入门的引导。本文不对技术细节过多探讨,细节方面会有相应的参考链接。
一、历史
插件化的历史已经有很长一段时间了,各种大大们也介绍过插件化相关的历史,比如:
包建强的:Android插件化:从入门到放弃
T大:Android 插件化 动态升级
张涛:Android 插件化的 过去 现在 未来
按照时间维度来看,整理成以下表格:
android_pluginAndroidDynamicLoader
AndroidDynamicLoader的作者是大众点评的屠毅敏,应该是最早的动态加载实现方案了。作者在介绍这个框架时形容宿主App就好像浏览器,但它加载的并不是网页,而是运行在Android系统上的插件。这个方案主要是在插件中使用Fragment,在宿主中使用Activity去动态加载插件中的Fragment。
github链接:https://github.com/mmin18/AndroidDynamicLoader
23Code
23Code并不是一个开源的项目,它是一个完整的apk。在应用市场可以下载得到,它内部展示了一些有趣的动效,通过下载的方式,可以直接运行起来,这就是插件化的真实案例。
Altas
altas是阿里的伯奎分享出来的一个插件化的方案。
分享视频链接:http://v.youku.com/v_show/id_XNTMzMjYzMzM2.html
对应的PPT:http://club.alibabatech.org/resource_detail.htm?topicId=84
这里的分享主要是将一些思路,业务方面的场景,解决的问题。后来github上有了对应的开源项目叫OpenAltas,后改名ACDD。
ACDD的链接:https://github.com/bunnyblue/ACDD
官方对这个库的说明是非代理Android动态热部署框架,而且在视频介绍中,伯奎也讲到,这个方案,就是把宿主当做一个容器,动态加载对应的插件。视频中也有讲到,要做到让插件无感知地运行在这个容器中,需要hook很多系统层面的东西,比如:ActivityThread,LoadedApk,ContextImpl,PackageParser,ActivityManagerNative等,即当插件需要系统的服务来提供对应功能的时候,将这个行为拦截掉,宿主就可以在插件和Android系统中间做些手脚了。在当时,Altas是最为先进插件化技术了。为淘宝客户端提供了很多加载其他业务插件的能力。
Dynamic-load-apk
Dynamic-Load-Apk简称DL,这个开源框架作者是任玉刚,他的实现方式是,在宿主中埋一个代理Activity,更改ClassLoader后找到加载插件中的Activity,使用宿主中的Activity作为代理,回调给插件中Activity所以对应的生命周期。这个思路与AndroidDynamicLoader有点像,都是做一个代理,只不过Dynamic-load-apk加载的插件中的Activity。
项目地址:https://github.com/singwhatiwanna/dynamic-load-apk
项目说明:http://blog.csdn.net/singwhatiwanna/article/details/40283117
DroidPlugin
DroidPlugin是张勇实现的一套插件化方案,它的原理也是Hook客户端一侧的系统Api,可能与Altas所Hook的点不同,细想应该是基本相同的。
项目地址:https://github.com/DroidPluginTeam/DroidPlugin
项目中DOC文件夹有很多关于项目的讲解说明。
张勇本人对DroidPlugin的讲解:http://www.infoq.com/cn/presentations/the-realization-principle-and-application-of-droidplugin?utm_campaign=rightbar_v2&utm_source=infoq&utm_medium=presentations_link&utm_content=link_text
维术对这个框架的讲解:http://weishu.me/2016/01/28/understand-plugin-framework-overview/
维术的这几篇blog很详细滴讲解了DroidPlugin是如何实现四大组件的插件化的,还有几篇有规划但是没有写的方面,希望后面能补全。
VirtualApp
VirtualApp作者是高中生罗迪,据说这个Android大牛初三的时候就开始研究双开、插件化的技术,相当了不起。项目的思路与DroidPlugin相似,不过他没有提供Service的代理,而是使用ContentProvider来代替Service在宿主中作为真正的运行体。
项目地址:https://github.com/asLody/VirtualApp
DynamicAPK
DynamicAPK是携程推出的动态加载方案
项目说明:http://www.infoq.com/cn/articles/ctrip-android-dynamic-loading
项目地址:https://github.com/CtripMobile/DynamicAPK
与ACDD一样修改了aapt,使得插件与宿主的资源不会出现相同id的问题。
热修复
插件化技术的演进,带来了相关的热修复技术。有代表的热修复技术有:
- QQ空间的超级补丁技术
- 微信Tinker
- 阿里的AndFix
QQ空间和微信的Tinker的细想很相近,都是在查找类的之前,将插件的dex插入原有dex之前,使得能够加载的是最新插入进来的dex中的class。从而达到修复原有类的问题的目的。它们并没有在Github上开源,贾吉鑫根据这个思路做出了Nuwa开源道github上,之后又有很多类似的开源项目。阿里的AndFix与这种思路不同,它采用的是方法替换的思路,在native层,把这个方法实现体的指针替换为修复后的方法。
这两种方案其实都有很多弊端,QQ空间的类替换方法,不能即时生效,patch如果修复的地方比较多,会影响启动时间。而AndFix,则只支持方法层面的替换,不能使用未import过的类,不能替换整个类文件。
美团有一种叫做Robust的热修复方案
链接:http://tech.meituan.com/android_robust.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
它应该是性能与修复场景最好的一种了。它的思想与InstantRun一样,在编译时动态地为每个类中的每个方法插桩,每个方法判断是否有插件被加载,有的话直接执行插件中的方法。
网友评论