有关Android插件化的一些总结思考,html5在移动端开发优势更明显

下面分析几个目前主流的开源框架,看看每个框架具体实现思路和优缺点。

####DL 动态加载框架 ( 2014 年底)

是基于代理的方式实现插件框架,对 App 的表层做了处理,通过在 Manifest 中注册代理组件,当启动插件组件时,首先启动一个代理组件,然后通过这个代理组件来构建,启动插件组件。 需要按照一定的规则来开发插件 APK,插件中的组件需要实现经过改造后的 Activity、FragmentActivity、Service 等的子类。

优点如下:

  • 插件需要遵循一定的规则,因此安全方面可控制。
  • 方案简单,适用于自身少量代码的插件化改造。

缺点如下:

  • 不支持通过 This 调用组件的方法,需要通过 that 去调用。
  • 由于 APK 中的 Activity 没有注册,不支持隐式调用 APK 内部的 Activity。
  • 插件编写和改造过程中,需要考虑兼容性问题比较多,联调起来会比较费时费力。

####DroidPlugin ( 2015 年 8 月)

DroidPlugin 是 360 手机助手实现的一种插件化框架,它可以直接运行第三方的独立 APK 文件,完全不需要对 APK 进行修改或安装。一种新的插件机制,一种免安装的运行机制,是一个沙箱(但是不完全的沙箱。就是对于使用者来说,并不知道他会把 apk 怎么样), 是模块化的基础。

实现原理:

  • 共享进程:为
    android提供一个进程运行多个 apk 的机制,通过 API 欺骗机制瞒过系统。
  • 占坑:通过预先占坑的方式实现不用在 manifest 注册,通过一带多的方式实现服务管理。
  • Hook 机制:动态代理实现函数 hook ,Binder 代理绕过部分系统服务限制,IO 重定向(先获取原始 Object –> Read ,然后动态代理 Hook Object 后–> Write 回去,达到瞒天过海的目的)。

插件 Host 的程序架构:

优点如下:

  • 支持 Android 四大组件,而且插件中的组件不需要在宿主 APK 中注册。
  • 支持 Android 2.3 及以上系统,支持所有的系统 API。
  • 插件与插件之间,插件与宿主之间的代码和资源完全隔阂。
  • 实现了进程管理,插件的空进程会被及时回收,占用内存低。

缺点如下:

  • 插件 APK 中不支持自定义资源的 Notification,通知栏限制。
  • 插件 APK 中无法注册具有特殊的 IntentFilter 的四大组件。
  • 缺乏对 Native 层的 Hook 操作,对于某些带有 Native 代码的插件 APK 支持不友好,可能无法正常运行。
  • 由于插件与插件,插件与宿主之间的代码完全隔离,因此,插件与插件,插件与宿主之间的通信只能通过 Android 系统级别的通信方式。
  • 安全性担忧(可以修改,hook一些重要信息)。
  • 机型适配(不是所有机器上都能行,因为大量用反射相关,如果rom厂商深度定制了framework层,反射的方法或者类不在,容易插件运用失败)

####Small ( 2015 年底)

Small 是一种实现轻巧的跨平台插件化框架,基于“轻量、透明、极小化、跨平台”的理念,实现原理有以下三点。

  • 动态加载类:我们知道插件化很多都从 DexClassLoader 类有个 DexPathList 清单,支持 dex/jar/zip/apk 文件格式,却没有支持 .so 文件格式,因此 Small 框架则是把 .so 文件包装成 zip 文件格式,插入到 DexPathList 集合中,改写动态加载的代码。
  • 资源分段:由于 Android 资源的格式是 0xPPTTNNNN ,PP 是包 ID ,00-02 是属于系统,7f 属于应用程序,03-7e 则保留,可以在这个范围内做文章 , TT 则是 Type 比如,attr 、layout 、string 等等,NNNN 则是资源全局 ID。那么这个框架则是对资源包进行重新打包,每个插件重新分配资源 ID ,这样就保证了宿主和插件的资源不冲突。
  • 动态代理注册:在 Android 中要使用四大组件,都是需要在 manifest 清单中注册,这样才可以使用,那如何在不注册情况也能使用呢,这里就是用到动态代理机制进行 Hook ,在发送 AMS 之前用占坑的组件来欺骗系统,通过认证后,再把真正要调用的组件还原回来,达到瞒天过海目的。

架构图:

优点如下:

  • 所有插件支持内置宿主包中。
  • 插件的编码和资源文件的使用与普通开发应用没有差别。
  • 通过设定 URI ,宿主以及 Native 应用插件,Web 插件,在线网页等能够方便进行通信。
  • 支持 Android 、 iOS 、和 Html5 ,三者可以通过同一套 Javascript 接口实现通信。

缺点如下:

  • 暂不支持 Service 的动态注册,不过这个可以通过将 Service 预先注册在宿主的 AndroidManifest.xml 文件中进行规避,因为 Service 的更新频率通常非常低。

与其他主流框架的区别:

DyLA : Dynamic-load-apk @singwhatiwanna
DiLA : Direct-Load-apk @FinalLody
APF : Android-Plugin-Framework @limpoxe
ACDD : ACDD @bunnyblue
DyAPK : DynamicAPK @TediWang
DPG : DroidPlugin @cmzy, 360

  • 功能

  • 透明度

####VirtualAPK  (2017年 6 月 )

VirtualAPK 是滴滴开源的一套插件化框架,支持几乎所有的 Android 特性,四大组件方面。

架构图:

实现思路:

VirtualAPK 对插件没有额外的约束,原生的 apk 即可作为插件。插件工程编译生成 apk后,即可通过宿主 App 加载,每个插件 apk 被加载后,都会在宿主中创建一个单独的 LoadedPlugin 对象。如下图所示,通过这些 LoadedPlugin 对象,VirtualAPK 就可以管理插件并赋予插件新的意义,使其可以像手机中安装过的 App 一样运行。

  • 合并宿主和插件的ClassLoader 需要注意的是,插件中的类不可以和宿主重复

  • 合并插件和宿主的资源 重设插件资源的 packageId,将插件资源和宿主资源合并

  • 去除插件包对宿主的引用 构建时通过 Gradle 插件去除插件对宿主的代码以及资源的引用

特性如下:

四大组件均不需要在宿主manifest中预注册,每个组件都有完整的生命周期。

  • Activity:支持显示和隐式调用,支持Activity的themeLaunchMode,支持透明主题;
  • Service:支持显示和隐式调用,支持Service的startstopbindunbind,并支持跨进程bind插件中的Service;
  • Receiver:支持静态注册和动态注册的Receiver;
  • ContentProvider:支持provider的所有操作,包括CRUDcall方法等,支持跨进程访问插件中的Provider。
  • 自定义View:支持自定义 View,支持自定义属性和style,支持动画;
  • PendingIntent:支持PendingIntent以及和其相关的AlarmNotificationAppWidget
  • 支持插件Application以及插件manifest中的meta-data
  • 支持插件中的so

优秀的兼容性

  • 兼容市面上几乎所有的Android手机,这一点已经在滴滴出行客户端中得到验证。
  • 资源方面适配小米、Vivo、Nubia 等,对未知机型采用自适应适配方案。
  • 极少的 Binder Hook,目前仅仅 hook了两个Binder:AMSIContentProvider,hook 过程做了充分的兼容性适配。
  • 插件运行逻辑和宿主隔离,确保框架的任何问题都不会影响宿主的正常运行。

入侵性极低

  • 插件开发等同于原生开发,四大组件无需继承特定的基类;
  • 精简的插件包,插件可以依赖宿主中的代码和资源,也可以不依赖;
  • 插件的构建过程简单,通过 Gradle 插件来完成插件的构建,整个过程对开发者透明。

如下是 VirtualAPK 和主流的插件化框架之间的对比。

特性DynamicLoadApkDynamicAPKSmallDroidPluginVirtualAPK
支持四大组件只支持Activity只支持Activity只支持Activity全支持全支持
组件无需在宿主manifest中预注册×
插件可以依赖宿主×
支持 PendingIntent×××
Android 特性支持大部分大部分大部分几乎全部几乎全部
兼容性适配一般一般中等
插件构建部署aaptGradle插件Gradle插件

####RePlugin  (2017 年 7 月)

RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案,由360手机卫士的RePlugin Team研发,也是业内首个提出”全面插件化“(全面特性、全面兼容、全面使用)的方案。

框架图:

主要优势有:

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

实战

主要是测试各个框架之间上手的容易度如何,并做不同对比,这边写了两个 Demo 例子,一个是基于 Small 框架,一个基于 VirtualAPK 框架,从中能看出不同。

####Small 实践

要引用官方最新的版本,不然在宿主和插件合并build.gradle 的时候会出现一个 BUG,这是个坑位,注意行走。其次在模块命名上要遵循一定的规则,比如业务模块用 app.* ,公共库模块用 lib.* ,相当于包名 .app.,.lib. 。每次在插件中添加一个 activity 组件,都需要在宿主中配置路由,然后在重新编译插件一遍,不然直接运行的话,在宿主中是找到新添加的 activity 组件,会报该组件没在系统 manifest 中,所以每次新增或修改建议插件都重新编译一遍。官方里说了,对于 Service 支持不太友好,就没去实践了。

####VirtualAPK 实践
有个坑需要注意的是构建环境,官方说明是要以下版本环境,Gradle 2.14.1 和 com.android.tools.build 2.1.3, 之前编译的是用最新的Gradle版本,导致一直有问题,至于是否有其他问题,可以看官方文档。

具体代码
vice 支持不太友好,就没去实践了。

####VirtualAPK 实践
有个坑需要注意的是构建环境,官方说明是要以下版本环境,Gradle 2.14.1 和 com.android.tools.build 2.1.3, 之前编译的是用最新的Gradle版本,导致一直有问题,至于是否有其他问题,可以看官方文档。

具体代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值