插件化和组件化

什么是组件化和插件化?

组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。
插件化开发和组件化开发略有不用,插件化开发时将整个app拆分成很多模块,这些模块包括一个宿主和多个插件,每个模块都是一个apk(组件化的每个模块是个lib),最终打包的时候将宿主apk和插件apk分开或者联合打包。

组件化和插件化对比:

技术单位实现内容灵活性特性静动态
组件化module是解耦与加快编译,隔离不需要关注的部分按加载时机切换,是作为lib,还是apk组:组本来就是一个系统,每个组件不是真正意义上的独立模块静态加载
插件化apk是解耦与加快编译,同时实现热插拔也就是热更新加载的是apk,可以动态下载,动态更新,比组件化更灵活插:是独立的apk,每个插件可以作为一个完全独立的apk运行,也可以和其他插件集成为大apk动态加载,只用真正使用某个插件时,才加载该插件

通过对比,我们可以看出组件化和插件化最大的不同点就是对线上已有模块动态新增和修改,其实这点组件化、插件化取舍的一个重要原则。但是,产品如果对动态性要求比较高,选择插件化时也要权衡俩方面,第一,插件化不可避免的需要调用系统很多api,存在很多兼容问题,因此需要专门团队来做插件化的开发;第二,复杂的业务逻辑进行插件化拆分,耗时很大,是否影响开发节奏。

  • 插件化可以动态增加和修改线上的模块;
  • 组件化的动态能力相对较弱,只能对线上已有模块进行动态的加载和卸载,不能新增和修改。

组件化

  1. 代码解耦问题
    对已存在的项目进行模块拆分,模块分为两种类型,一种是功能组件模块,封装一些公共的方法服务等,作为依赖库对外提供,一种是业务组件模块,专门处理业务逻辑等功能,这些业务组件模块最终负责组装APP。
  2. 组件单独运行问题
    通过 Gradle 脚本配置方式,进行不同环境切换。比如只需要把 Apply plugin: ‘com.android.library’ 切换成Apply plugin: ‘com.android.application’ 就可以,同时还需要在 AndroidManifest 清单文件上进行设置,因为一个单独调试需要有一个入口的 Activity。比如设置一个变量 isModule,标记当前是否需要单独调试,根据isModule 的取值,使用不同的 gradle 插件和 AndroidManifest 清单文件,甚至可以添加 Application 等 Java 文件,以便可以做一下初始化的操作。
  3. 组件间通信问题
    通过接口+实现的结构进行组件间的通信。每个组件声明自己提供的服务 Service API,这些 Service 都是一些接口,组件负责将这些 Service 实现并注册到一个统一的路由 Router 中去,如果要使用某个组件的功能,只需要向Router 请求这个 Service 的实现,具体的实现细节我们全然不关心,只要能返回我们需要的结果就可以了。在组件化架构设计图中 Common 组件就包含了路由服务组件,里面包括了每个组件的路由入口和跳转。
  4. UI 跳转问题
    可以说 UI 跳转也是组件间通信的一种,但是属于比较特殊的数据传递。不过一般 UI 跳转基本都会单独处理,一般通过短链的方式来跳转到具体的 Activity。每个组件可以注册自己所能处理的短链的 Scheme 和 Host,并定义传输数据的格式,然后注册到统一的 UIRouter 中,UIRouter 通过 Scheme 和 Host 的匹配关系负责分发路由。但目前比较主流的做法是通过在每个 Activity 上添加注解,然后通过 APT 形成具体的逻辑代码。目前方式是引用阿里的 ARouter 框架,通过注解方式进行页面跳转。
  5. 组件生命周期问题
    在架构图中的核心管理组件会定义一个组件生命周期接口,通过在每个组件设置一个配置文件,这个配置文件是通过使用注解方式在编译时自动生成,配置文件中指明具体实现组件生命周期接口的实现类,来完成组件一些需要初始化操作并且做到自动注册,暂时没有提供手动注册的方式。
  6. 集成调试问题
    每个组件单独调试通过并不意味着集成在一起没有问题,因此在开发后期我们需要把几个组件机集成到一个 APP 里面去验证。由于经过前面几个步骤保证了组件之间的隔离,所以可以任意选择几个组件参与集成,这种按需索取的加载机制可以保证在集成调试中有很大的灵活性,并且可以加大的加快编译速度。需要注意的一点是,每个组件开发完成之后,需要把 isModule 设置为 true并同步,这样主项目就可以通过参数配置统一进行编译。
  7. 代码隔离问题
    如果还是 compile project(xxx:xxx.aar) 来引入组件,我们就完全可以直接使用到其中的实现类,那么主项目和组件之间的耦合就没有消除,那之前针对接口编程就变得毫无意义。我们希望只在 assembleDebug 或者 assembleRelease 的时候把 AAR 引入进来,而在开发阶段,所有组件都是看不到的,这样就从根本上杜绝了引用实现类的问题。

目前做法是主项目只依赖 Common 的依赖库,业务组件通过路由服务依赖库按需进行查找,用反射方式进行组件加载,然后在主工程中调用组件服务,组件与组件之间调用则是通过接口+实现进行通信,后续规划通过自定义Gradle 插件,通过字节码自动插入组件的依赖进行编译打包,实现自动筛选 assembleDebug 或 assembleRelease 这两个编译命任务,只有属于包含这两个任务的命令才引入具体实现类,其他的则不引入。

组件化架构图:
在这里插入图片描述
配合ARouter(https://github.com/alibaba/ARouter) 做路由跳转界面。

插件化

随着下面这些问题的出现:

  1. APP的体积越来越大,功能模块越来越多
  2. 模块之间的耦合度高,协同开发沟通成本越来越大
  3. 方法数目可能超过65535,APP占用的内存过大
    相应的解决办法:
  4. 将一个大的APK按照业务划分为多个小的APK
  5. 每个小的APK又可以独立运行、又可以依附于宿主APK运行
    那么,就会有如下优势:
  6. 业务模块之间基本完全解偶
  7. 协同并行开发成为可能,提高了Gradle的编译速度
  8. 业务模块可以按照需要进行加载,降低内存的占用
    于是乎,插件化的技术油然而生。

在插件化的技术中,有几个常见的属于:

  1. 宿主:主APP,也叫作Host,它可以独立运行,也可以加载插件。宿主必须安装到用户手机上,提供基本的类库与功能
  2. 插件:也叫作Plugin,跟普通APP一样,可以独立运行,也可以由宿主进行加载
  3. 插件化:将一个应用按照宿主&插件的方式改造的过程就叫做插件化

使用类库
1.DroidPlugin
是360手机助手在Android系统上实现了一种新的插件机制
2.Android-Plugin-Framework
此项目是Android插件开发框架完整源码及示例。用来通过动态加载的方式在宿主程序中运行插件APK。
3.Small
世界那么大,组件那么小。Small,做最轻巧的跨平台插件化框架。里面有很详细的文档
4.dynamic-load-apk
Android 使用动态加载框架DL进行插件化开发
5.AndroidDynamicLoader
Android 动态加载框架,他不是用代理 Activity 的方式实现而是用 Fragment 以及 Schema 的方式实现
6.DynamicAPK
实现Android App多apk插件化和动态加载,支持资源分包和热修复.携程App的插件化和动态加载框架.
7.ACDD
非代理Android动态部署框架
8.android-pluginmgr
不需要插件规范的apk动态加载框架。
9.VirtualAPK
VirtualAPK是滴滴出行自研的一款优秀的插件化框架。
10.android-pluginmgr
不需要插件规范的apk动态加载框架。
11.RePlugin
RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案,由360手机卫士的RePlugin Team研发,也是业内首个提出”全面插件化“(全面特性、全面兼容、全面使用)的方案。
在这里插入图片描述

主流框架

在 Android 中实现插件化框架,需要解决的问题主要如下:

  1. 资源和代码的加载
  2. Android 生命周期的管理和组件的注册
  3. 宿主 APK 和插件 APK 资源引用的冲突解决
DL 动态加载框架 ( 2014 年底)

GItHub:https://github.com/singwhatiwanna/dynamic-load-apk
DL支持的功能
1、plugin无需安装即可由宿主调起。
2、支持用R访问plugin资源
3、plugin支持Activity和FragmentActivity(未来还将支持其他组件)
4、基本无反射调用
5、插件安装后仍可独立运行从而便于调试
6、支持3种plugin对host的调用模式:
(1)无调用(但仍然可以用反射调用)。
(2)部分调用,host可公开部分接口供plugin调用。 这前两种模式适用于plugin开发者无法获得host代码的情况。
(3)完全调用,plugin可以完全调用host内容。这种模式适用于plugin开发者能获得host代码的情况。
7、只需引入DL的一个jar包即可高效开发插件,DL的工作过程对开发者完全透明
8、支持android2.x版本
DL框架原理
动态加载主要有两个需要解决的复杂问题:资源的访问和activity生命周期的管理,除此之外,还有很多坑爹的小问题,而DL框架很好地解决了这些问题。需要说明的一点是,我们不可能调起任何一个未安装的apk,这在技术上是很难实现的,我们调起的apk必须受某种规范的约束,只有在这种约束下开发的apk,我们才能将其调起。


DroidPlugin ( 2015 年 8 月)

Github:https://github.com/DroidPluginTeam/DroidPlugin
DroidPlugin 是 360 手机助手实现的一种插件化框架,它可以直接运行第三方的独立 APK 文件,完全不需要对 APK 进行修改或安装。一种新的插件机制,一种免安装的运行机制,是一个沙箱(但是不完全的沙箱。就是对于使用者来说,并不知道他会把 apk 怎么样), 是模块化的基础。
DroidPlugin 插件机制 :它可以在无需安装、修改的情况下运行APK文件,此机制对改进大型APP的架构,实现多团队协作开发具有一定的好处。
项目新地址:DroidPlugin
定义:
HOST程序:插件的宿主。
插件:免安装运行的APK
限制和缺陷:

  1. 无法在插件中发送具有自定义资源的Notification,例如:
    a. 带自定义RemoteLayout的Notification
    b. 图标通过R.drawable.XXX指定的通知(插件系统会自动将其转化为Bitmap)
  2. 无法在插件中注册一些具有特殊Intent Filter的Service、Activity、BroadcastReceiver、ContentProvider等组件以供Android系统、已经安装的其他APP调用。
  3. 缺乏对Native层的Hook,对某些带native代码的apk支持不好,可能无法运行。比如一部分游戏无法当作插件运行。

特点:

  1. 支持Androd 2.3以上系统
  2. 插件APK完全不需做任何修改,可以独立安装运行、也可以做插件运行。要以插件模式运行某个APK,你无需重新编译、无需知道其源码。
  3. 插件的四大组件完全不需要在Host程序中注册,支持Service、Activity、BroadcastReceiver、ContentProvider四大组件
  4. 插件之间、Host程序与插件之间会互相认为对方已经"安装"在系统上了。
  5. API低侵入性:极少的API。HOST程序只是需要一行代码即可集成Droid Plugin
  6. 超强隔离:插件之间、插件与Host之间完全的代码级别的隔离:不能互相调用对方的代码。通讯只能使用Android系统级别的通讯方法。
  7. 支持所有系统API
  8. 资源完全隔离:插件之间、与Host之间实现了资源完全隔离,不会出现资源窜用的情况。
  9. 实现了进程管理,插件的空进程会被及时回收,占用内存低。
  10. 插件的静态广播会被当作动态处理,如果插件没有运行(即没有插件进程运行),其静态广播也永远不会被触发。

Small ( 2015 年底)

Github:https://github.com/wequick/Small
官网:http://code.wequick.net/Small
Small 是一种实现轻巧的跨平台插件化框架,基于“轻量、透明、极小化、跨平台”的理念
在这里插入图片描述

优点如下:
1.所有插件支持内置宿主包中。
2.插件的编码和资源文件的使用与普通开发应用没有差别。
3.通过设定 URI ,宿主以及 Native 应用插件,Web 插件,在线网页等能够方便进行通信。
4.支持 Android 、 iOS 、和 Html5 ,三者可以通过同一套 Javascript 接口实现通信。
缺点如下:
暂不支持 Service 的动态注册,不过这个可以通过将 Service 预先注册在宿主的 AndroidManifest.xml 文件中进行规避,因为 Service 的更新频率通常非常低。


VirtualAPK (2017年 6 月 )

Github:https://github.com/didi/VirtualAPK
VirtualAPK 是滴滴开源的一套插件化框架,支持几乎所有的 Android 特性,四大组件方面。
原理:
VirtualAPK 对插件没有额外的约束,原生的 apk 即可作为插件。插件工程编译生成 apk后,即可通过宿主 App 加载,每个插件 apk 被加载后,都会在宿主中创建一个单独的 LoadedPlugin 对象。如下图所示,通过这些 LoadedPlugin 对象,VirtualAPK 就可以管理插件并赋予插件新的意义,使其可以像手机中安装过的 App 一样运行。

  • 合并宿主和插件的ClassLoader 需要注意的是,插件中的类不可以和宿主重复
  • 合并插件和宿主的资源 重设插件资源的 packageId,将插件资源和宿主资源合并
  • 去除插件包对宿主的引用 构建时通过 Gradle 插件去除插件对宿主的代码以及资源的引用
    特性如下:
    四大组件均不需要在宿主manifest中预注册,每个组件都有完整的生命周期。
  1. Activity:支持显示和隐式调用,支持Activity的theme和LaunchMode,支持透明主题;
  2. Service:支持显示和隐式调用,支持Service的start、stop、bind和unbind,并支持跨进程bind插件中的Service;
  3. Receiver:支持静态注册和动态注册的Receiver;
  4. ContentProvider:支持provider的所有操作,包括CRUD和call方法等,支持跨进程访问插件中的Provider。
  5. 自定义View:支持自定义 View,支持自定义属性和style,支持动画;
  6. PendingIntent:支持PendingIntent以及和其相关的Alarm、Notification和AppWidget;
  7. 支持插件Application以及插件manifest中的meta-data;
  8. 支持插件中的so。
    优秀的兼容性
  • 兼容市面上几乎所有的Android手机,这一点已经在滴滴出行客户端中得到验证。
  • 资源方面适配小米、Vivo、Nubia 等,对未知机型采用自适应适配方案。
  • 极少的 Binder Hook,目前仅仅 hook了两个Binder:AMS和IContentProvider,hook 过程做了充分的兼容性适配。
  • 插件运行逻辑和宿主隔离,确保框架的任何问题都不会影响宿主的正常运行。

RePlugin (2017 年 7 月)

GitHub:https://github.com/Qihoo360/RePlugin
RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案,由360手机卫士的RePlugin Team研发,也是业内首个提出”全面插件化“(全面特性、全面兼容、全面使用)的方案。
其主要优势有:

  • 极其灵活:主程序无需升级(无需在Manifest中预埋组件),即可支持新增的四大组件,甚至全新的插件
  • 非常稳定:Hook点仅有一处(ClassLoader),无任何Binder Hook!如此可做到其崩溃率仅为“万分之一”,并完美兼容市面上近乎所有的Android ROM
  • 特性丰富:支持近乎所有在“单品”开发时的特性。包括静态Receiver、Task-Affinity坑位、自定义Theme、进程坑位、AppCompat、DataBinding等
  • 易于集成:无论插件还是主程序,只需“数行”就能完成接入
  • 管理成熟:拥有成熟稳定的“插件管理方案”,支持插件安装、升级、卸载、版本管理,甚至包括进程通讯、协议版本、安全校验等
  • 数亿支撑:有360手机卫士庞大的数亿用户做支撑,三年多的残酷验证,确保App用到的方案是最稳定、最适合使用的
    截止2017年6月底,RePlugin的:
特性描述
插件数103(核心57个)
插件占应用比高达83%
年发版次数高达596次(工作日均2次)
崩溃率万分之一(0.01%),极低
时间2014年应用,3年验证

目前360公司几乎所有的亿级用户量的APP,以及多款主流第三方APP,都采用了RePlugin方案

特性
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值