Android
插件化技术是比较热门领域,VirtualAPK 是滴滴2017年6月3号开源,框架功能完备,支持 Android
四大组件,良好的兼容性,且入侵性较低,作为加载耦合插件方案是较好选择。兼容市面上几乎所有的 Android
手机,这一点已经在滴滴出行客户端中得到验证; 资源方面适配小米、Vivo
、Nubia
等,对未知机型采用自适应适配方案;极少的 Binder Hook
,目前仅仅hook
了两个 Binder
: AMS
和 IContentProvider
,hook
过程做了充分的兼容性适配;插件运行逻辑和宿主隔离,确保框架的任何问题都不会影响宿主的
特性 | DynamicLoadApk | DynamicAPK | Small | DroidPlugin | VirtualAPK |
---|---|---|---|---|---|
支持四大组件 | 只支持Activity | 只支持Activity | 只支持Activity | 全支持 | 全支持 |
组件无需在宿主manifest中预注册 | √ | × | √ | √ | √ |
插件可以依赖宿主 | √ | √ | √ | × | √ |
支持PendingIntent | × | × | × | √ | √ |
Android特性支持 | 大部分 | 大部分 | 大部分 | 几乎全部 | 几乎全部 |
兼容性适配 | 一般 | 一般 | 中等 | 高 | 高 |
插件构建 | 无 | 部署aapt | Gradle插件 | 无 | Gradle插件 |
Service Runtime
去处理,Service Runtime
会接管系统的所有操作;Provider Runtime
去处理,Provider Runtime
会接管系统的所有操作。 鸿洋大神写的源码分析(滴滴官网都推荐看鸿洋大神写的)
滴滴插件化方案 VirtualApk 源码解析
下面这位大神就不知道是谁了(滴滴官网推荐看的)
VirtualAPK 资源加载机制分析
比如宿主compile了如下aar
compile 'com.didi.virtualapk:core:0.9.0'//滴滴VirtualAPK的依赖
compile 'com.alibaba:fastjson:1.2.39'
compile'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
插件工程需要访问宿主sdk中的类和资源,那么可以在插件工程中同样compile sdk的aar,如下:
compile 'com.didi.virtualapk:core:0.9.0'//滴滴VirtualAPK的依赖
compile 'com.alibaba:fastjson:1.2.39'
compile'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
这样一来,插件工程就可以正常地引用sdk了。并且,插件构建的时候会自动将这个aar从apk中剔除
build.gradle
中添加dependencies {
classpath 'com.didi.virtualapk:gradle:0.9.0'
}
build.gradle
中顶部添加
apply plugin: 'com.didi.virtualapk.host'
build.gradle
中 compile
添加dependencies {
compile 'com.didi.virtualapk:core:0.9.0'
}
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
PluginManager.getInstance(context).init();
}
PluginManager pluginManager = PluginManager.getInstance(this);
//此处是当查看插件apk是否存在,如果存在就去加载(比如修改线上的bug,把插件apk下载到sdcard的根目录下取名为Demo.apk)
File apk = new File(Environment.getExternalStorageDirectory(), "Demo.apk");
if (apk.exists()) {
try {
pluginManager.loadPlugin(apk);
} catch (Exception e) {
e.printStackTrace();
}
}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
build.gradle
中添加dependencies {
classpath 'com.didi.virtualapk:gradle:0.9.0'
}
build.gradle
中顶部添加依赖以及插件配置信息
apply plugin: 'com.didi.virtualapk.plugin'//注意这个是plugin结尾,宿主是以host结尾的
// 插件配置信息,放在文件最下面
virtualApk {
// 插件资源表中的packageId,需要确保不同插件有不同的packageId.
packageId = 0x6f
// 宿主工程application模块的路径,插件的构建需要依赖这个路径,我这个宿主工程和插件工程在同一级目录下,所以下面这样写
targetHost = '../VirtualAPKHostDemo/app'
//默认为true,如果插件有引用宿主的类,那么这个选项可以使得插件和宿主保持混淆一致
applyHostMapping = true
目前VirtualAPK构建器还在持续完善之中,因此插件构建推荐使用Gradle 2.14.1版本,3.x版本可能有适配问题,我们正在努力去兼容各种Gradle版本。同时,待VirtualAPK构建器完善之后,其代码也将开源,敬请期待。
估计大部分还不知道怎么构建吧, 我是用git构建的
进入F:\ARWorkSpace\VirualAPKPluginDemo,点击右键Git Bash Here
输入
./gradlew clean assemblePlugin(这个本人测试通过)
或者
gradle clean assemblePlugin(这个本人测试没有成功,不知道为什么)
来构建构建完成之后再F:\ARWorkSpace\VirualAPKPluginDemo\app\build\outputs\plugin\release有个apk这个就是插件apk,如下图位置
assemblePlugin
依赖于assembleRelease
,这意味着:
- 插件包均是Release包,不支持debug模式的插件包
- 如果存在多个productFlavors,那么将会构建出多个插件包
- 插件包位于build目录下