Skip to content

xuancao/VirtualApkProgram

Repository files navigation

virtualapk对编译环境有很大的限制,我宿主项目和插件项目中使用的编译环境是:'com.android.tools.build:gradle:3.1.0'(刚更新了,支持3.1.0)

但是插件项目中编译环境还得依赖'com.android.tools.build:gradle:2.3.3'(使用3.1.0出现错误,所以插件和宿主暂时还是统一使用稳定的2.3.3)

宿主和插件app---build.gradle中均已更新至最新为 'com.didi.virtualapk:core:0.9.7-dev'

下周再修改配置集成新的试试

com.didi.virtualapk:gradle:0.9.8.5-dev --- 适配com.android.tools.build:gradle:3.1.0。 --- 修复当插件未定义attr资源时anim资源找不到的bug。

一、插件集成

1、项目的build.gradle添加依赖

buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.0' classpath 'com.didi.virtualapk:gradle:0.9.4'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

}

2、宿主app中build.gradle添加依赖

头部添加:

apply plugin: 'com.didi.virtualapk.host'

在dependencies添加:

compile 'com.didi.virtualapk:core:0.9.7-dev'

3、在在App的工程模块proguard-rules.pro文件添加混淆规则:

-keep class com.didi.virtualapk.internal.VAInstrumentation { *; }

-keep class com.didi.virtualapk.internal.PluginContentResolver { *; }

-dontwarn com.didi.virtualapk.**

-dontwarn android.**

-keep class android.** { *; }

4、初始化

在合适的地方添加: PluginManager.getInstance(context).init();

5、加载模块

//初始化插件管理器

PluginManager pluginManager = PluginManager.getInstance(context.getApplicationContext());

//获取插件APK的文件对象

File apk = getPluginFile(context, pluginId);

if (apk.exists()){ try { //加载插件 pluginManager.loadPlugin(apk); return true; } catch (Exception e) { e.printStackTrace(); } }

检测模块是否已经加载:

PluginManager pluginManager = PluginManager.getInstance(context.getApplicationContext());

//获取指定包名的插件对象

if (pluginManager.getLoadedPlugin(PackageName) != null){

return true; //已经加载

}

启动模块界面: if(isPluginLoaded(activity,pluginId)){ //模块是否加载,pluginId为model中设置的插件id

//代表模块加载成功 页面可赢正常跳转功能

try {

    Intent intent = new Intent();

    intent.setClassName(packageName, className);

    activity.startActivity(intent);

}catch (Exception e){

    e.printStackTrace();

    Log.e("sun", "startActivity: " +"启动插件失败");

}

return true;

}

二、插件工程接入 插件项目根的build.gradle添加依赖

buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.didi.virtualapk:gradle:0.9.4' } }

头部添加: apply plugin: 'com.didi.virtualapk.plugin' 添加依赖: //引入virtualAPK依赖 compile 'com.didi.virtualapk:core:0.9.7-dev'

插件信息配置:

virtualApk {

//Attention:::packageId 范围 0x02 - 0x7E
packageId = 0x61             // 插件资源id,避免资源id冲突

targetHost ='app'            // 宿主工程的路径

applyHostMapping = true      // 插件编译时是否启用应用宿主的apply mapping

}

生成插件:

最后一步生成插件,需要使用Gradle命令(在Terminal中执行,或者在醒目目录中执行)

gradle clean assemblePlugin

三、运行插件

1、demo中的plugin是push到模拟器或者手机的指定目录中。(真实项目应该是从服务器下载)

2、运行宿主app,在指定位置启动model就可以了(参考:一、插件集成中的5步骤)

注意: 模块的文件名称和路径要和代码中保持一致

/**

  • 通过插件id获取插件文件对象
  • @param context
  • @param pluginId
  • @return, 返回插件文件对象 */

public static File getPluginFile(Context context, int pluginId){

//定义插件apk的名称

String pluginApkName = getPluginName(pluginId);  //demo中做了简单封装,根据pluginId获model的包名

//定义插件文件对象

File file = new File(FileUtils.getPluginCacheDir(), pluginApkName);

return file;

}

本项目说明:

支持将插件存放到本地assets里面进行加载,也可从网络中下载插件进行加载(需在Func中修改apk存放服务器地址url)

通信:本项目中单个进程中(单个app内部)用的是EventBus消息传递机制, 多个app通信(多个app通信,eg:登录插件NativePlugin中登录后通知宿主和RemotePlugin插件修改登录状态)采用的是广播机制进行的消息传递,取数据采用ContentProvider方式 跨进程通信 可以采取Messenger,AIDL,ContentProvider,Socket的方式,根据个人喜好选择 didi/VirtualAPK Demo中的宿主向插件中取数据采用ContentProvider方式

RemotePlugin插件中需要进行修改用户信息,但是用户信息要从宿主中得到(此处用跨进程通信。可以用aidl进行通信(所操作实体类还是都要定义相同的包名和类名,感觉直接使用intent简单),也可以直接用Intent传递,需要将所传的UserInfo类在宿主和插件中定义为相同包名和类名)

可以采用共享缓存数据+广播来处理数据变化+通知UI更新

问题记录:

1、宿主app启动插件,插件没有启动,而是重新开启了一个宿主Activity。

原因:插件界面的布局名和宿主app的布局名称重复。

解决办法:virtualapk中插件的资源文件名称避免和宿主重复,包括图片、布局、颜色和尺寸资源,否则会直接调用宿主中的资源。

插件如果和宿主同事依赖了相同的包,打包时插件也不会携带该包,直接使用宿主的包文件。

2.在AIDL文件中引用的Java类不会自动引入引用包名,需要在UserInfoManager.aidl中手动添加 import com.virtual.xuancao.virtualapkprogram.model.UserInfoModel;

3.插件编译时报host异常,需要宿主添加 apply plugin: 'com.didi.virtualapk.host',但项目中已添加,试试重启项目,再进行编译

About

组件化、插件化、基于VirtualAPK所做的插件化项目

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages