首先奉上Virtualapk 的github地址:https://github.com/didi/VirtualAPK
VirtualAPK是滴滴出行自研的一款优秀的插件化框架,它的介绍这里就不说了,自行查看wiki文档,这里只给出最基础的接入方法以及注意点:
宿主程序(主app):
首先project的gradle中添加:
classpath 'com.didi.virtualapk:gradle:0.9.0'
在app的gradle中添加
apply plugin: 'com.didi.virtualapk.host' dependencies { ... compile 'com.didi.virtualapk:core:0.9.0' }
gradle编译完成后,新建android的Application类,在attachBaseContext方法中对插件进行初始化操作:
public class VitrualAPKApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); PluginManager.getInstance(base).init(); } }
插件的安装与跳转:
在我们需要的地方安装插件:
PluginManager pluginManager = PluginManager.getInstance(this); File apk = new File(Environment.getExternalStorageDirectory(), "plugin.apk"); if (apk.exists()) { try { pluginManager.loadPlugin(apk); } catch (Exception e) { e.printStackTrace(); } }
从宿主跳转到插件:
String packageName = "com.xiaoqi.vitrualapkplugin"; if (PluginManager.getInstance(this).getLoadedPlugin(packageName) == null) { Toast.makeText(this, "plugin [com.xiaoqi.vitrualapkplugin] not loaded", Toast.LENGTH_SHORT).show(); return; }else { Intent intent = new Intent(); intent.setClassName("com.xiaoqi.vitrualapkplugin", "com.xiaoqi.vitrualapkplugin.MainActivity"); startActivity(intent); }
宿主到目前为止以及接入完成。
插件的开发:
同样在project的gradle中加入:
classpath 'com.didi.virtualapk:gradle:0.9.0'
在app的gradel中加入:
dependencies { ... compile 'com.didi.virtualapk:core:0.9.0' } apply plugin: 'com.didi.virtualapk.plugin' virtualApk { packageId = 0x6f // the package id of Resources. targetHost = '../VirtualAPKDemo/app' // the path of application module in host project. applyHostMapping = true //optional, default value: true. }
插件与宿主的交互
跳转方式和之前相同:
Intent intent = new Intent(); intent.setClassName("com.xiaoqi.virtualapkdemo", "com.xiaoqi.virtualapkdemo.MainActivity"); startActivity(intent);
通过反射去调用主程序代码:
Context context = PluginManager.getInstance(getApplicationContext()).getHostContext().getApplicationContext(); Class<Context> contextClass = (Class<Context>) context.getClass(); try { Field field = contextClass.getField("i"); int a = field.getInt(context); tvContent.setText("" + a); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
其实到这里插件就已经完成了,接下来就可以调用gradlew clean assemblePlugin指令,编译生成apk,放入sd卡中给宿主加载即可。
注意点
1、插件必须至少有一个资源id,否则会报错
2、0.9.0版本只支持gradle 2.1.3
3、宿主和插件的资源名称不要相同,比如有两个布局叫activity_main就会出现异常