WXDynamicPlugin

Introduction: 自研零反射,零 HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构,适合小,中,大型项目均可的插件化架构
More: Author   ReportBugs   OfficialWebsite   
Tags:

介绍

WXDynamicPlugin 是由本人自住研发的 Android 插件框架

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

示例 Sample

扫码下载

示例 Sample 截图

与市面上其他插件框架相比,WXDynamicPlugin 主要具有以下优势和特点

优势:

1.支持宿主就一个空壳子,并且启动速度不受任何影响,做到真正原生不用发版

2.插件打包支持“分布式”,多模块单独插件,单独下载,单独加载,单独访问

3.支持接入到宿主的那仅有的一小部分代码 都可以动态更新(插件下载逻辑,版本管理,下载服务器地址,环境全动态化)

4.支持 Debug 调试插件,不存在插件调试难度

特点:

  • 零反射无 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
  • fragment
  • assets
  • 插件访问宿主类
  • 插件之间可以互不依赖,也可以存在有依赖关系
  • 通知栏
  • So 加载
  • 分段加载插件(多 Apk 分别加载或多 Apk 以此依赖加载)
  • 一个 app 分多个模块单独加载
  • 一个 Activity 中加载多个 Apk 中的 View
  • 支持插件调试 debug
  • 支持 Compose
  • 等等……

插件化框架对比

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

编译与开发环境

环境准备

  • AS 设置 JDK 选 17,电脑 java 版本需要安装 1.8.xxx, 打开工程下 local.properties
以下为我本地电脑配置,需要添加一行下面一句,并改成自己电脑配置:
 workingDirPath=D\:\\android_software\\android_sdk\\android_sdk\\build-tools\\32.0.0\\
然后在 IDE 中选择 app 或 sample 模块直接运行,如下:

项目工程目录截图

项目工程目录介绍

文件夹 介绍 接入方式
WX-Code 示例工程全源码级接入方式 接入方式一:依赖 host 模块工程
WX-Dynamic-Host-SDK-Lib 宿主工程所依赖的 lib 工程源码
WX-Maven 示例工程 maven 依赖仓库方式接入工程 接入方式二:maven 引入 host 包
  • 特别说明:WX-Code 和 WX-Maven 下实际代码内容一样,目录结构一样,唯一区别接入全动态 host 代码方式不一样,另外 WX-Maven 下所有文件夹和项目工程名多了 maven 前缀,用于在同一工程下区分成 2 个不同的项目

推荐用方式二: Maven 接入方式

为了方便编译和看,已经注释掉 settings.gradle 中第 35 行到 137 行,需要看源码及源码方式接入(WX-Code 下面),请自行放开注释

以 WX-Maven 下目录结构介绍为例:

WX-Host: 下面全部为 host 宿主项目代码

  sample: host 宿主真实工程 app

  sample-lib: 下面为宿主工程依赖的 4 个工程模块

    maven-wgllss-business-re-library:涉及到 app 的公共业务带 res 资源的模块 lib
    maven-wgllss-common-re-library:涉及到公共代码带 res 资源的模块 lib
    maven-wgllss-dynamic-host-library:宿主里 manifest 注册所必备的四大组件等 lib
    maven-wgllss-dynamic-host-skin-resource-lib:宿主所必须的资源样式主题等 lib

WX-Plugin: 该文件夹下面的所有工程都是插件的形式,不存在宿主里面

  Maven-Wgllss-Dynamic-Plugin-Common-Library: 插件中公共代码
  Maven-Wgllss-Dynamic-Plugin-Generate: 插件中打包所用的 apt 工程
  Maven-Wgllss-Dynamic-Plugin-Manager: 插件中管理插件,管理动态代码的 3 个工程
  Maven-Wgllss-Dynamic-Plugin-Sample: 插件中真正业务代码插件工程
  Maven-Wgllss-Dynamic-Plugin-SDK: 插件框架四大组件 SDK 代码,以插件形式存在
  Maven-Wgllss-Dynamic-Plugin_Skin: 插件中换皮肤资源

WX-Resource: 为项目已经打包好的插件,so,皮肤包文件等 存放的文件夹

上面介绍 直接 run 运行 ,打开 app 进入宿主,直接下载的插件 为我已经放在准好的服务器上面了

  可以通过源码工程自行打包,上传到自己的服务器上部署,方法如下:
  找到 WX/WX-Maven/WX-Host/sample/ com.wgllss.dynamic.host.FaceImpl

  //    override fun getHostL() = "http://192.168.3.21:8080/assets/WXDynamicPlugin/"
//    override fun getHostL() = "http://192.168.1.9:8080/assets/WXDynamicPlugin/"
    //todo 自己本地搭一个服务器,或者 自己服务器 或者 像我一样在 gitee 上面在自己的项目下建一个文件当作服务器 供下载,
    // 切记不要往往我的 gitee 项目上面推
    override fun getHostL() = "https://gitee.com/wgllss888/WXDynamicPlugin/raw/master/WX-Resource/"

    /** 0:WXDynamicPlugin 动态化插件框架 理论上已经做到了可以完全不动宿主,但是如果一定要动宿主 可以提供以下思路:
     *  1:可以根据 宿主版本号得到 宿主版本支持的 的插件,
     *  2:当宿主必须 需要升级时,升级后原版本的插件不可用了,插件配置在新宿主版本文件夹下面,原宿主版本文件夹可可以先动态配置 在启动页 升级下载新的宿主
     *  @example  宿主版本 10000 版本支持的插件 放在服务端 WXDynamicPlugin/10000/ 文件夹下  20000 版本的插件放在 WXDynamicPlugin/20000/下面
     */
    override fun getBaseL(): String {
        if (TextUtils.isEmpty(baseXL)) {
            baseXL = StringBuilder().append(getHostL()).append(DeviceIdUtil.getDeviceId()).append("/").append(BuildConfig.VERSION_CODE).append("/").toString()
        }
        return baseXL
    }

  修改 getHostL() 地址为自己服务器地址, 修改 getBaseL() 中主要路劲,确保修改后地址可以访问通
  然后将打包好的 14 个文件 放入 getHostL()+getBaseL() 服务器文件夹下面
  该 14 个文件打包如下:

  点击 assembleCreateAllFileRelease 等待 14 个文件生成 ,一次不行,再次点击执行命令,如果还不生成,点击当前项目下 maven-wgllss-sample-create-version-config-app 的另一个 assembleCreateVersion2FileRelease,生成 2 个文件之后再执行 assembleCreateAllFileRelease
  14 个文件生成在以下目录:可以拷贝到自己的服务器上面供下载:即上面修改的 getHostL()+getBaseL() 服务器文件夹下面 ,同时把我准备的 WX-Resource/so 文件夹和 WX-Resource/skins 文件夹拷贝过去,这是供 sample 工程演示所用的,另外皮肤资源包多个 apk 文件也可以自行通过源码工程打包

全动态插件化框架 WXDynamicPlugin 介绍文章:

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

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

(三)插件化框架内部详细介绍: 零反射,零 HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构

(四)插件化框架接入详细指南:零反射,零 HooK,全动态化,插件化框架,全网唯一结合启动优化的插件化架构

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

(六) 大型项目架构:解析全动态插件化框架 WXDynamicPlugin 是如何做到全动态化的?

(七) 还在不断升级发版吗?从 0 到 1 带你看懂 WXDynamicPlugin 全动态插件化框架?

(八) Compose 插件化:一个 Demo 带你入门 Compose,同时带你入门插件化开发

(九) 花式高阶:插件化之 Dex 文件的高阶用法,极少人知道的秘密

(十) 5 种常见 Android 的 SDK 开发的方式,你知道几种?

(十一) 5 种 WebView 混合开发动态更新方式,直击痛点,有你想要的?

(十二) Compose 的全动态插件化框架支持了,已更新到 AGP 8.6,Kotlin2.0.20,支持 Compose

作者开源 Compose 可视化图表库

(一)Compose 曲线图表库 WXChart,你只需要提供数据配置就行了\

(二)Compose 折线图,贝赛尔曲线图,柱状图,圆饼图,圆环图。带动画和点击效果\

(三)全网最火视频,Compose 代码写出来,动态可视化趋势视频,帅到爆\

(四)全网最火可视化趋势视频实现深度解析,同时新增条形图表

本人其他开源文章:

那些大厂架构师是怎样封装网络请求的?

Kotlin+协程+Flow+Retrofit+OkHttp 这么好用,不运行安装到手机可以调试接口吗?可以自己搭建一套网络请求工具

花式封装:Kotlin+协程+Flow+Retrofit+OkHttp +Repository,倾囊相授,彻底减少模版代码进阶之路

注解处理器在架构,框架中实战应用:MVVM 中数据源提供 Repository 类的自动生成

Android 串口,USB,打印机,扫码枪,支付盒子,键盘,鼠标,U 盘等开发使用一网打尽

多台 Android 设备局域网下的数据备份如何实现?

轻松搞定 Android 蓝牙打印机,双屏异显及副屏分辨率适配解决办法

一个 Kotlin 版 Demo 带你入门 JNI,NDK 编程

感谢阅读,欢迎给给个星,你们的支持是我开源的动力

欢迎光临:

我的掘金地址

关于我

VX 号:wgllss ,如果想更多交流请加我 VX

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools