在Android插件化技术日新月异的今天,开发并落地一款插件化框架到底是简单还是困难,这个问题不同人会有不同的答案。但是我相信,完成一个插件化框架的demo并不是多难的事,但是要开发一款完善的插件化框架却不是一件容易的事,尤其在国内,各大Rom厂商都对Android系统做了一定程度的定制,这进一步加剧了Android本身的碎片化问题。
\\我们在2016年开始研究这方面的技术,经过半年的开发、测试、适配和线上验证,目前推出了一款比较完善的插件化框架:VirtualAPK。
\\ \\之所以现在推出来,是因为VirtualAPK在我们内部已经得到了很好的验证,我们在迭代过程中不断地做机型适配和细节特性的支持,目前已经达到一个非常稳定的状况,足以支撑滴滴部分乃至全部业务的动态发版需求。目前VirtualAPK应用于滴滴乘客端和优步中国APP中,大家可以去体验。
\\为了更好地体现出VirtualAPK的价值,我们决定将其开源,请猛击https://github.com/didi/VirtualAPK 。
\\VirtualAPK也是滴滴公司的首个对外开源项目,欢迎大家star、发送pull request,也欢迎大家来使用VirtualAPK,我们会给予一定的技术支持。
\\VirtualAPK能为我们带来什么?
\\在传统的APP发布过程中,总是存在着固定的发版节奏,比如两周或者一个月更新一次,这固然没有问题。但考虑一种情况,如果一个版本刚发布出去,却发现存在大量crash,这个时候我们会怎么办?大多数公司都会选择立刻发一个紧急版本,然后一批人需要手忙脚乱甚至加班来准备这个版本,所以紧急版本还是越少越好。
\\其实不仅仅是因为致命crash而紧急发版,比如一个早期创业公司,需要通过迅速的“试错”来尝试找准市场的方向,这个时候就需要更加紧凑的发版方式,有些时候甚至想一天发一次版。在正常的发版流程中,这显然是不现实的。但是如果这家创业公司必须要随时可以发版,否则就可能被竞争对手抢占先机,这个时候该怎么办呢?
\\上述的这两个问题,通过VirtualAPK,将不再是问题。通过VirtualAPK将业务模块插件化,然后就可以随时通过更新插件的方式来发布新功能,不管是修复致命crash还是进行业务“试错”,都是一种很爽快的体验。
\\VirtualAPK的特性
\\VirtualAPK是滴滴出行自研的一款优秀的插件化框架,主要有如下几个特性。
\\功能完备
\\四大组件均不需要在宿主manifest中预注册,每个组件都有完整的生命周期。
\\优秀的兼容性
\\入侵性极低
\\VirtualAPK和主流开源框架的对比
\\如下是VirtualAPK和主流的插件化框架之间的对比。
\\ \\为什么选择VirtualAPK?
\\已经有那么多优秀的开源的插件化框架,滴滴为什么要重新造一个轮子呢?
\\1. 大部分开源框架所支持的功能还不够全面 除了DroidPlugin,大部分都只支持Activity。
\\2. 兼容性问题严重,大部分开源方案不够健壮 由于国内Rom尝试深度定制Android系统,这导致插件框架的兼容性问题特别多,而目前已有的开源方案中,除了DroidPlugin,其他方案对兼容性问题的适配程度是不足的。
\\3. 已有的开源方案不适合滴滴的业务场景 虽然说DroidPlugin从功能的完整性和兼容性上来看,是一款非常完善的插件框架,然而它的使用场景和滴滴的业务不符。
\\DroidPlugin侧重于加载第三方独立插件,比如微信,并且插件不能访问宿主的代码和资源。而在滴滴打车中,其他业务模块均需要宿主提供的订单、定位、账号等数据,因此插件不可能和宿主没有交互。
\\其实在大部分产品中,一个业务模块实际上并不能轻而易举地独立出来,它们往往都会和宿主有交互,在这种情况下,DroidPlugin就有点力不从心了。
\\基于上述几点,我们只能重新造一个轮子,它不但功能全面、兼容性好,还必须能够适用于有耦合的业务插件,这就是VirtualAPK存在的意义。
\\在加载耦合插件方面,VirtualAPK是开源方案的首选,推荐大家使用。
\\通俗易懂地说
\\抽象地说
\\VirtualAPK的工作过程
\\VirtualAPK对插件没有额外的约束,原生的apk即可作为插件。插件工程编译生成apk后,即可通过宿主App加载,每个插件apk被加载后,都会在宿主中创建一个单独的LoadedPlugin对象。如下图所示,通过这些LoadedPlugin对象,VirtualAPK就可以管理插件并赋予插件新的意义,使其可以像手机中安装过的App一样运行。
\\ \\如何使用
\\第一步: 初始化插件引擎
\\\@Override\\protected void attachBaseContext(Context base) {\\ super.attachBaseContext(base);\\ PluginManager.getInstance(base).init();\\}
\\
第二步:加载插件
\\\public class PluginManager {\\ public void loadPlugin(File apk);\\}
\\
当插件入口被调用后,插件的后续逻辑均不需要宿主干预,均走原生的Android流程。 比如,在插件内部,如下代码将正确执行:
\\\@Override\\protected void onCreate(Bundle savedInstanceState) {\\ super.onCreate(savedInstanceState);\\ setContentView(R.layout.activity_book_manager);\\ LinearLayout holder = (LinearLayout)findViewById(R.id.holder);\\ TextView imei = (TextView)findViewById(R.id.imei);\\ imei.setText(IDUtil.getUUID(this));\\ \\ // bind service in plugin\\ Intent service = new Intent(this, BookManagerService.class);\\ bindService(service, mConnection, Context.BIND_AUTO_CREATE);\\ \\ // start activity in plugin\\ Intent intent = new Intent(this, TCPClientActivity.class);\\ startActivity(intent);\\}
\\
探究原理
\\基本原理
\\四大组件的实现原理
\\如下是VirtualAPK的整体架构图,更详细的内容请大家阅读源码和wiki。
\\