(一)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构
(二)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构
(三)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构
(四)零反射,零HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构(五) 大型项目架构:全动态插件化+模块化+Kotlin+协程+Flow+Retrofit+JetPack+MVVM+极限瘦身+极限启动优化+架构示例+全网唯一
(六) 大型项目架构:解析全动态插件化框架WXDynamicPlugin是如何做到全动态化的?
(七) 还在不断升级发版吗?从0到1带你看懂WXDynamicPlugin全动态插件化框架
(八) Compose插件化:一个Demo带你入门Compose,同时带你入门插件化开发
(九) 花式高阶:插件化之Dex文件的高阶用法,极少人知道的秘密
插件化发展史
对于Android 插件化思路,也已经研究了好多年了,市面上也出现了好多插件化框架,比较著名的如下:
-
AndroidDynamicLoader:给予 Fragment 实现了插件化框架,可以动态加载插件中的 Fragment 实现页面的切换;
-
dynamic-load-apk(任玉刚) :最早使用ProxyActivity这种静态代理技术,由ProxyActivity去控制插件中PluginActivity的生命周期(缺点:插件中的activity必须继承PluginActivity,开发时要小心处理context);
-
DroidPlugin:通过Hook系统服务的方式启动插件中的Activity,使得开发插件的过程和开发普通的app没有什么区别(缺点:由于hook过多系统服务,异常复杂且不够稳定)
-
携程 DynamicApk
-
VirtualApp:能够完全模拟app的运行环境,能够实现app的免安装运行和双开技术
-
Small: 一个跨平台插件化框架
-
360 RePlugin
-
滴滴 VirtualApk
-
阿里 Atlas:一个结合组件化和热修复技术的一个app基础框架,号称是一个容器化框架
-
满帮集团:Phantom
-
腾讯 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 对比启动速度
- Protobuf 减小通信数据
- OKIO 优化io读取
- 引入exoPlayer 播放器
- 启动优化性能做到极致,接入插件化后的app快于各大厂主流没有接入插件化app 启动时间
- Room数据库
- 全MD设计
- 工程全动态化的插件化框架(包括宿主下载都可以动态化)
- 插件内部MVVM架构
- 涉及到APT注解处理,ASM字节码插桩功能
- 涉及到ANT,NDK,JNI,,C,C++编程
- 工程全Kotlin实现,涉及到协程 ,Flow
插件化框架对比
插件化框架 | Shadow | WXDynamicPlugin |
---|---|---|
插件打包体积 | 3M以上 | 500k左右 |
极致化下载管理版本控制 | 需自己实现 | 1步到位 |
插件加载逻辑 | 宿主->管理器->插件 | 宿主->插件 |
首次插件下载到展示首页耗时 | 3~5s以上? | 1s内 |
插件已经到本地后加载速度 | 1500ms以上 | 500ms内 |
全动态化 | 支持 | 支持 |
插件化框架动态化 | 支持 | 支持 |
下载逻辑代码动态化 | 不支持 | 支持 |
版本控制代码动态化 | 不支持 | 支持 |
插件调试debug | 不支持 | 支持 |
启动性能对比:
1、同一手机 2、都安装release包 3、都是非深色模式 和非深色模式 4、手机大约都在同一时间范围内测试,保证电池电量等相关硬件相差不大
下面安装release包,非深色模式下,在 mate30 pro 5g上查看启动速度,依次为 支付宝 微信 美团 和本软件
对比结果
软件 | 支付宝 | 微信 | 美团 | WXMusic |
---|---|---|---|---|
启动耗时平均(ms) | 458 | 409 | 817 | 242 |
相对速度快 | 47% | 40% | 70% | -- |
WxMusic > 微信 > 支付宝 > 美团
当然,对比条件还有一条,包体积相差不大,但全动态化插件化,本身宿主体积及已经极度瘦身了
致谢
Shadow | 动态插件化借鉴处理ClassLoader |
---|---|
ExoPlayer | 谷歌开源音视频播放器 |
UAMP | 音频播放器写法 |
Timber | 借鉴部分写法 |