最近公司打算重构已有项目,打算把项目插件化处理,网上找了很多资料,发现滴滴公司的VirtualApk符合我们的业务需求。
本文主要讲解构建宿主工程和插件工程中遇到的各种问题。

一、Cannot invoke method getAt() on null object

请至少添加一个宿主工程或其它插件所没有的资源文件,随意一张图片都可以
参考地址

二、The directory of host application doesn’t exist!

1
2
3
4
5
virtualApk {
packageId = 0x5f // the package id of Resources.
targetHost = 'C:/Users/utstarcom/Desktop/VR_TEST/PluginTestMain/app' // the path of application module in host project.
applyHostMapping = true //optional, default value: true.
}
  • packageId 位数不能超过3位,如0x5aa就会构建失败
  • targetHost 路径需要是宿主工程app的绝对路径

三、gradle 配置的坑

除了工程root根目录的build.gradle需要使用

1
classpath 'com.android.tools.build:gradle:2.1.3'

还需要修改工程根目录/gradle/weapper/gradle-wrapper.properties内容为:

1
2
3
4
5
6
#Thu Sep 14 16:39:28 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

四、宿主跳转插件的Activity

宿主跳转插件的Activity总会跳转到宿主的Activity中,但是却走了onCreate.
原因是,插件的activity的xml文件名和宿主中的文件名与宿主工程中layout中的某个xml文件名一致
如:
宿主工程有一个activity_main.xml文件
而插件工程的Activity的布局文件名也为activity_main.xml就会出现上面的问题。
解决方案,将插件工程中的那个重名的xml文件重命名。

ps: .java 文件则不受这个限制

五、一个build后无法动态注册的bug

你不能build后再使用插件打包,你需要使用gradle的同步功能同步一下后,再直接运行assemblePlugin插件,否则,宿主工程打开插件会提示插件的activity不能被注册到AndroidMainfest

六、插件卸载

有的时候,我们需要重新从服务器卸载插件,并让其实时生效,要达到这样的效果,可以通过反射的机制吧mPlugins这个map对应的LoadedPlugin,然后重新使用框架加载插件。卸载插件的具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 卸载插件
*
* @param pkg 插件包名
*/
private void unInstallPlugin(String pkg) {
PluginManager pluginManager = PluginManager.getInstance(this);
if (pluginManager.getLoadedPlugin(pkg) != null) {
try {
Field mPlugins = pluginManager.getClass().getDeclaredField("mPlugins");
mPlugins.setAccessible(true);
Map<String, LoadedPlugin> map = (Map<String, LoadedPlugin>) mPlugins.get(pluginManager);
if (map != null) {
map.remove(pkg);
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

七、宿主Host_R.txt生成失败

原因: apply plugin: 'com.didi.virtualapk.host'插件加载到了apply plugin: 'com.android.application'之前

解决:修改宿主app的gradle.build文件

1
2
apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.host'

然后clean工程就会自动生成了

八、宿主version.txt not found

宿主工程build一次就可以生成了

九、插件启动插件

如果你希望在插件A启动插件B。

正确的做法是:在插件A中加载插件B,然后才能在插件A中启动插件B

这就是目前碰到的一些奇葩问题,后续如果继续碰到相应的问题,会继续更新

demo地址