零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构(一)

3,941 阅读8分钟

(一)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构
(二)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构
(三)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构
(四)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构

(五) 大型项目架构:全动态插件化+模块化+Kotlin+协程+Flow+Retrofit+JetPack+MVVM+极限瘦身+极限启动优化+架构示例+全网唯一

(六) 大型项目架构:解析全动态插件化框架WXDynamicPlugin是如何做到全动态化的?
(七) 还在不断升级发版吗?从0到1带你看懂WXDynamicPlugin全动态插件化框架
(八) Compose插件化:一个Demo带你入门Compose,同时带你入门插件化开发
(九) 花式高阶:插件化之Dex文件的高阶用法,极少人知道的秘密

插件化发展史

对于Android 插件化思路,也已经研究了好多年了,市面上也出现了好多插件化框架,比较著名的如下:

  1. AndroidDynamicLoader:给予 Fragment 实现了插件化框架,可以动态加载插件中的 Fragment 实现页面的切换;

  2. dynamic-load-apk(任玉刚) :最早使用ProxyActivity这种静态代理技术,由ProxyActivity去控制插件中PluginActivity的生命周期(缺点:插件中的activity必须继承PluginActivity,开发时要小心处理context);

  3. DroidPlugin:通过Hook系统服务的方式启动插件中的Activity,使得开发插件的过程和开发普通的app没有什么区别(缺点:由于hook过多系统服务,异常复杂且不够稳定)

  4. 携程 DynamicApk

  5. VirtualApp:能够完全模拟app的运行环境,能够实现app的免安装运行和双开技术

  6. Small: 一个跨平台插件化框架

  7. 360 RePlugin

  8. 滴滴 VirtualApk

  9. 阿里 Atlas:一个结合组件化和热修复技术的一个app基础框架,号称是一个容器化框架

  10. 满帮集团:Phantom

  11. 腾讯 Shadow:一个完全无Hack,甚至零反射实现的Android插件框架,插件的代码完全是一个正常可安装的App代码,无需引用任何Shadow的库

插件化框架对比

上述插件化框架源码 1,2, 3, 4, 9, 10, 11 大都看过研究过,也实战过,尤其是时间相对近点的 Phantom 和 Shadow 都实战过,但总是不能满足我的需求,我需求是:

1. 宿主只能是一个空的壳子
2. 插件的体积必须做到极限小
3. 插件化框架SDK必须可以动态化
4. 宿主安装完第一次启动后必须就开始下载,下载完就进入首页,启动时间又不能太长

研究结果下来,Phantom 和 Shadow 已经之前的插件化框架 都满足宿主是 一个壳子 ,但是插件体积太大,简单的一个插件apk 也要3M左右,如果首次启动就下载3M,再怎么也要10多s时间,下载完再加载耗时,这远远满足不了我的需求,就算弄一个障眼法广告 或者动画也很影响体验。于是,我自行研发了一套插件化框架就诞生了WXDynamicPlugin

WXDynamicPlugin

介绍

WXDynamicPlugin是由本人自住研发的Android插件框架 与市面上其他插件框架相比,WXDynamicPlugin主要具有以下特点:

  • 零反射无Hack实现插件技术:从理论上就已经确定无需对任何系统做兼容开发,更无任何隐藏API调用,和Google限制非公开SDK接口访问的策略完全不冲突。
  • 全动态插件框架:一次性实现完美的插件框架很难,但WXDynamicPlugin将这些全部动态化来实现,使插件化框架代码也成为了插件,同时,宿主下载插件的逻辑,版本控制也可以插件化起来,使得插件的迭代,及插件化框架的修改,以及可能涉及到宿主下载插件逻辑,版本控制逻辑,加载插件逻辑,这些全部动态化起来。目前市面上插件化框架,都没有实现插件下载到本地逻辑的动态化起来
  • 插件极限瘦身优化:编译出插件体积最小,所有插件模块总体积加载起来不到500k,单个模块70k左右,同时可以让各个功能模块单独插件化起来,市面上插件化框架插件体积编译出来基本都3M以上
  • 宿主增量极小:接入宿主的代码全Kotlin实现,真正插件化框架实现宿主接入代码仅4K多,加上下载逻辑,插件版本控制加载接入宿主代码仅60k左右,加上下载版本判断逻辑总共方法数仅80个方法数
  • 极限启动优化性能:做到宿主空壳子,第一次启动就下载到本地到加载,到显示到第一个页面,所需要的总耗时最小,基本是秒开,这得益于插件模块编译出来体积最小化,4G网络基本500ms就下载完了,如果插件编译出来基本3M以上,那么从服务端下载到本地至少10s以上,第一次再加载一个3M的插件又去了2~3s,第一次进入到主UI界面,差不多20s去了。而WXDynamicPlugin真正做到接入插件化后都比各大厂主流顶级App,没有通过宿主接插件化启动时间还快

支持特性

  • 四大组件 Activity ,Service , ContentProvider ,Broadcaster
  • 跨进程使用插件Service
  • 插件访问宿主类
  • 插件之间可以互不依赖,也可以存在有依赖关系
  • 通知栏
  • So加载
  • 分段加载插件(多Apk分别加载或多Apk以此依赖加载)
  • 一个app 分多个模块单独加载
  • 一个Activity中加载多个Apk中的View
  • 支持插件调试debug
  • 等等……

实例音乐软件截图展示:

软件架构

动态音乐第一版本,可自行搜索听收费音乐 全动态化插件化,涉及相关功能和知识:

下载安装release版本 或者自行 assembleRelease 打包 release 版本 和各大厂app 对比启动速度

  1. Protobuf 减小通信数据
  2. OKIO 优化io读取
  3. 引入exoPlayer 播放器
  4. 启动优化性能做到极致,接入插件化后的app快于各大厂主流没有接入插件化app 启动时间
  5. Room数据库
  6. 全MD设计
  7. 工程全动态化的插件化框架(包括宿主下载都可以动态化)
  8. 插件内部MVVM架构
  9. 涉及到APT注解处理,ASM字节码插桩功能
  10. 涉及到ANT,NDK,JNI,,C,C++编程
  11. 工程全Kotlin实现,涉及到协程 ,Flow

插件化框架对比

插件化框架ShadowWXDynamicPlugin
插件打包体积3M以上500k左右
极致化下载管理版本控制需自己实现1步到位
插件加载逻辑宿主->管理器->插件宿主->插件
首次插件下载到展示首页耗时3~5s以上?1s内
插件已经到本地后加载速度1500ms以上500ms内
全动态化支持支持
插件化框架动态化支持支持
下载逻辑代码动态化不支持支持
版本控制代码动态化不支持支持
插件调试debug不支持支持

启动性能对比:

1、同一手机 2、都安装release包 3、都是非深色模式 和非深色模式 4、手机大约都在同一时间范围内测试,保证电池电量等相关硬件相差不大
下面安装release包,非深色模式下,在 mate30 pro 5g上查看启动速度,依次为 支付宝 微信 美团 和本软件

al.jpg

tx.jpg

mt.jpg

wxmusic.jpg

对比结果

软件支付宝微信美团WXMusic
启动耗时平均(ms)458409817242
相对速度快47%40%70%--
WxMusic > 微信 > 支付宝 > 美团
当然,对比条件还有一条,包体积相差不大,但全动态化插件化,本身宿主体积及已经极度瘦身了

致谢

Shadow动态插件化借鉴处理ClassLoader
ExoPlayer谷歌开源音视频播放器
UAMP音频播放器写法
Timber借鉴部分写法

下一篇:零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构(二)