APP插件化/组件化框架分析
VirtualAPK插件框架简单使用
阿里Atlas组件框架使用
最近一段时间在研究插件化和组件化实现方案,今天也算整理一下笔记记录一下,记得之前讲述过一篇关于组件化的文章【Android 组件化之初探】,刚好对应着阿里的Atlas组件化框架,今天主要做个大致的介绍,稍后再逐个讲述下各框架的接入方法以及具体使用方法。
一、模块化、插件化和组件化
1. 模块化、插件化和组件化的关系
在技术开发领域,模块化是指分拆代码,即当我们的代码特别臃肿的时候,用模块化将代码分而治之、解耦分层。具体到 android 领域,模块化的具体实施方法分为插件化和组件化。
2. 插件化和组件化的区别
一套完整的插件化或组件化都必须能够实现单独调试、集成编译、数据传输、UI 跳转、生命周期和代码边界这六大功能。
插件化和组件化最重要而且是唯一的区别的就是:
- 插件化可以动态增加和修改线上的模块;
- 组件化的动态能力相对较弱,只能对线上已有模块进行动态的加载和卸载,不能新增和修改。
插件化
插件化开发是将一个项目app拆分成多个模块,这些模块包括宿主和插件。每个模块相当于一个apk,而组件化相当于一个lib。最终发布的时候将宿主apk和插件apk单独打包或者联合打包。
作用
- 并发开发
每个组负责一个插件,彼此之间没有过多的依赖,可以单独调试打包。有时发版其实就相当于发插件。 - 动态更新插件
通过推送插件更新来修复bug。 - 按需下载模块
用户需要使用到对应模块的时候,才去下载相应模块。 - 方法数或变量数爆棚问题
组件化
组件化开发是将一个项目app拆分成多个模块,每个模块都是一个组件,组件化开发过程中相互依赖或单独调试,最终发布的时候是将这些组件合并统一成一个apk。
3. 插件化 和 组件化如何选择
在插件化和组件化取舍的一个重要原则是:APP 是否有动态增加或修改线上模块的需求,如果这种动态性的需求很弱,就不需要考虑插件化,一般说来,电商类或广告类产品对这个需求比较强烈,而类似“得到 APP”这类的知识服务产品,每个功能的推出都是经过精细打磨的,对这种即时的动态性要求不高,所以不需要采用插件化。
如果你的产品对动态性的要求比较高,那么在选择插件化之前也需要从两个方面权衡一下。一是插件化不可避免的去 hook 一些系统的 api,也就不可避免地有兼容性的问题,因此每个插件化方案需要有专门的团队去负责维护;二是从一个业务逻辑复杂的项目中去拆分插件化需要的时间可能是非常巨大的,需要考虑对开发节奏的影响。
因此,对大多数产品来说,组件化都是一个不错甚至最佳的选择,它没有兼容性,可以更方便地拆分,并且几乎没有技术障碍,可以更顺利地去执行。特别是对急需拆分的产品来说,组件化是一个可退可守的方案,可以更快地执行下去,并且将来要是迁移到插件化,组件化拆分也是必经的一步。
二、插件化和组件化方案
-
DynamicAPK (携程)
DynamicAPK 已停止维护- 只支持四大组件中的Activity
- 组件需要在宿主程序的manifest中预注册
- 不支持PendingIntent
- 插件构建需要部署aapt
- 支持大部分Android特性
- 兼容性适配一般
-
VirtualAPK (滴滴)
VirtualAPK GitHub- 四大组件全支持
- 组件不需要在宿主程序manifest中预注册
- 支持PendingIntent
- 插件构建Gradle插件
- 支持几乎全部的Android特性
- 兼容性适配比较高
- 兼容 Android O
- 加载apk
目前暂不支持的特性
- 暂不支持Activity的一些不常用特性(比如process、configChanges等属性),但是支持theme、launchMode和screenOrientation属性;
- overridePendingTransition(int enterAnim, int exitAnim)这种形式的转场动画,动画资源不能使用插件的(可以使用宿主或系统的);
- 插件中弹通知,需要统一处理,走宿主的逻辑,通知中的资源文件不能使用插件的(可以使用宿主或系统的)。
-
Atlas(阿里手淘)
atlas GitHub
Atlas 文档
Atlas是伴随着手机淘宝的不断发展而衍生出来的一个运行于Android系统上的一个容器化框架,我们也叫动态组件化(Dynamic Bundle)框架。它主要提供了解耦化、组件化、动态性的支持。
Atlas-手淘组件化框架的前世今生和未来的路
阿里巴巴开源移动容器化框架Atlas的技术演进之路
atlas支持所有的代码及资源更新,暂时不支持新增4大组件- bundle可以直接使用host中的代码和资源
- Atlas基本上基于Module开发,这里所说的直接使用host中的代码和资源是通过将host中的公用代码和资源抽离成一个中间件middlewarelibrary,在各bundle中的build中通过使用providedCompile project(':middlewarelibrary')
来使用其中的代码。 - 有时插件可能需要访问host里面的资源或者代码(如appname,launcher),可以单独建一个library存放公共资源和代码,并且一些公共的三方库引用也可以放到里面,这样所有插件都只需要以provided的方式引这个library就可以,不用在每个插件里面都引用相同的库。
- 官方demo中文件
-
RePlugin(360手机卫士)
https://github.com/Qihoo360/RePlugin
完整的:让插件运行起来“像单品那样”,支持大部分特性
稳定的:如此灵活完整的情况下,其框架崩溃率仅为业内很低的“万分之一”
适合全面使用的:其目的是让应用内的“所有功能皆为插件”
占坑类:以稳定为前提的Manifest占坑思路
插件化方案:基于Android原生API和语言来开发,充分利用原生特性
加载jar
四种方案比较与选择
插件化.png在 加载耦合插件 方面,VirtualAPK 是开源方案的首选,推荐大家使用。
通俗易懂地说——
- 如果你是要加载微信、支付宝等第三方 APP,那么推荐选择 RePlugin;
- 如果你是要加载一个内部业务模块,并且这个业务模块很难从主工程中解耦,那么 VirtualAPK 是最好的选择。
抽象地说——
- 如果你要加载一个插件,并且这个插件无需和宿主有任何耦合,也无需和宿主进行通信,并且你也不想对这个插件重新打包,那么推荐选择 RePlugin;
- 除此之外,在同类的开源中,推荐大家选择 VirtualAPK。