VirtualAPK的简单集成采坑

今天打算研究下VirtualAPK,因为公司项目要改成插件化,开始研究滴滴开源的VirtualAPK,大概了解以后当然要简单集成下看看效果,下面记录下过程顺便说说踩的坑。

版本问题

网上找到的集成教程都是0.9.0版本的,但是GitHub上的最新的版本是0.9.8.6,所以我使用的是最新的版本,结果是集成失败,最后还是换回了0.9.0版本

Gradle的build tools版本问题

开始使用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

同步time out

在我使用 0.9.0版本的VirtualAPK结合2.14.1的Gradle和的build tools配置完以后,要进行同步,同步了多次都是出现gradle time out 的提示,开始以为是哪里配置错了,后来多次尝试终于成功,其实哪里也没有修改,就等待就OK,这里我要能够了大概20多分钟。

找不到文件app\build\VAHost\versions.txt

最后通过gradlew clean assemblePlugin命令编译插件,报出这个错误,这个是因为我在编译之前clean了程序,导致build目录中的一些文件没有了,只要在rebuild一下目录就OK

前两个问题是版本的问题,版本没有选对就会出现各种奇葩的错误,这里就不一一列举了,解决办法就是直接换版本就OK,下面来说集成流程,网上教程较多,我就的简单说。

1:创建宿主和插件

在一个工程中创建两个Module,一个当做宿主工程,一个当做插件工程,在项目的根目录的build.gradle添加配置classpath 'com.didi.virtualapk:gradle:0.9.0'
这里写图片描述
可以看到virtualAPK的版本使用的0.9.0,build tools版本使用的2.1.3

2:配置宿主工程

(1)在宿主Module中的build.gradle中的添加如下配置:

apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.host'   `//宿主工程插件

android {
    ...
    ...
}
dependencies {
   ...
   ...
    compile 'com.didi.virtualapk:core:0.9.0' //核心类
}

(2)创建Application

在宿主工程中创建一个MyApplication,继承Application(在Manifest文件中配置),重写attachBaseContext类,在这里进行VirtualAPK的初始化:

public class MyApplication extends Application{
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        PluginManager.getInstance(base).init();
    }
}

(3)在适当位置加载插件,可以在Application中,也可以在Activity中,反正越早越好

注意:插件如果放在了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();
        }
    }

(4)加载插件

然后我在宿主工程中添加了一个按钮,用来加载插件工程的Activity

public void click(View view){
        Intent intent = new Intent();
        intent.setClassName("com.emm.plugin","com.emm.plugin.Main2Activity");
        startActivity(intent);
    }

3:配置插件工程

在插件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主要是当生成插件的时候,要去访问宿主工程的一些资源做一些处理,其他的看注释吧。

注意:插件工程里的类名和布局文件的名字不要和宿主工程中起的一样,否则容易出现问题。

4:生成插件

到此配置完成,同步一下,没有问题的话,通过命令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

你可能感兴趣的:(VirtualAPK的简单集成采坑)