今天打算研究下VirtualAPK,因为公司项目要改成插件化,开始研究滴滴开源的VirtualAPK,大概了解以后当然要简单集成下看看效果,下面记录下过程顺便说说踩的坑。
网上找到的集成教程都是0.9.0版本的,但是GitHub上的最新的版本是0.9.8.6,所以我使用的是最新的版本,结果是集成失败,最后还是换回了0.9.0版本
开始使用0.9.8.6版本的时候,因为看网上有的说使用3.0的build tools也有说使用2.1.3的build tools,我想既然我用的最新的VirtualAPK版本应该是用3.0以后的build tools版本把,就使用的3.0的build tools,最后集成失败,又换回了2.1.3的build tools,对应的Gradle版本是2.14.1
在我使用 0.9.0版本的VirtualAPK结合2.14.1的Gradle和的build tools配置完以后,要进行同步,同步了多次都是出现gradle time out 的提示,开始以为是哪里配置错了,后来多次尝试终于成功,其实哪里也没有修改,就等待就OK,这里我要能够了大概20多分钟。
最后通过gradlew clean assemblePlugin
命令编译插件,报出这个错误,这个是因为我在编译之前clean了程序,导致build目录中的一些文件没有了,只要在rebuild一下目录就OK
前两个问题是版本的问题,版本没有选对就会出现各种奇葩的错误,这里就不一一列举了,解决办法就是直接换版本就OK,下面来说集成流程,网上教程较多,我就的简单说。
在一个工程中创建两个Module,一个当做宿主工程,一个当做插件工程,在项目的根目录的build.gradle添加配置classpath 'com.didi.virtualapk:gradle:0.9.0'
可以看到virtualAPK的版本使用的0.9.0,build tools版本使用的2.1.3
apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.host' `//宿主工程插件
android {
...
...
}
dependencies {
...
...
compile 'com.didi.virtualapk:core:0.9.0' //核心类
}
在宿主工程中创建一个MyApplication,继承Application(在Manifest文件中配置),重写attachBaseContext
类,在这里进行VirtualAPK的初始化:
public class MyApplication extends Application{
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
PluginManager.getInstance(base).init();
}
}
注意:插件如果放在了SD卡中,如果targetVersion版本为23及以上,要动态申请权限
private void loadPlugin(Context base) {
PluginManager pluginManager = PluginManager.getInstance(base);
File apk = new File(Environment.getExternalStorageDirectory(), "plugin.apk");
if (apk.exists()) {
try {
pluginManager.loadPlugin(apk);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(),
"SDcard根目录未检测到plugin.apk插件", Toast.LENGTH_SHORT).show();
}
}
然后我在宿主工程中添加了一个按钮,用来加载插件工程的Activity
public void click(View view){
Intent intent = new Intent();
intent.setClassName("com.emm.plugin","com.emm.plugin.Main2Activity");
startActivity(intent);
}
在插件Module中的build.gradle中的添加如下配置:
apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.plugin' `//宿主工程插件
android {
...
...
}
dependencies {
...
...
compile 'com.didi.virtualapk:core:0.9.0' //核心类
}
virtualApk {
packageId = 0x6f // 插件资源id,避免资源id冲突
targetHost='D:/source/workspace_AS/VirtualAPK/app' // 宿主工程的路径,可以是绝对路径,可以是相对路径
applyHostMapping = true // 插件编译时是否启用应用宿主的apply mapping
}
在插件工程中比宿主工程多了一些配置,targetHost
主要是当生成插件的时候,要去访问宿主工程的一些资源做一些处理,其他的看注释吧。
注意:插件工程里的类名和布局文件的名字不要和宿主工程中起的一样,否则容易出现问题。
到此配置完成,同步一下,没有问题的话,通过命令gradlew clean assemblePlugin
生成插件即可,在AS的Terminal中来到项目的根目录中,执行上面的命令,如果没有问题最后会有BUILD SUCCESSFUL
的提示,然后在插件项目中的build --> outputs --> apk
中生成插件apk。修改插件的名字放到对应的加载位置即可。
运行宿主APK,然后点击按钮测试。
官方GitHub列举的常见问题地址:常见问题
参考链接:
https://github.com/didi/VirtualAPK
https://www.jianshu.com/p/b78087d0d524
https://blog.csdn.net/qq_15330241/article/details/78869843