在项目整合的过程中,要使用到插件化,听说360的RePlugin 还不错,所以就按照文档学习了一下,在此记录一下里面的坑。
项目地址:https://github.com/Qihoo360/RePlugin
首先,我们需要Replugin有一个简单的认识,它是一个框架,你开发的app可以作为插件直接安装到宿主app中,直接完美运行。而这个插件可以随时安装和卸载,非常方便。对于需要频繁更新的app或者使用频率比较低的模块,可以使用RePlugin,做到及时更新和用时加载。而且它的文档看上去还比较清晰,而且都是中文的,这个国内的人应该都比较喜欢。
所以我们需要提取两个重量级的概念:宿主APP和插件APP。
宿主APP主要是个壳子,用来作为插件app运行的容器
而插件APP可以是我们开发的一个个模块,然后你把模块扔到宿主app中安装,解压,然后就可以用其中的业务了。
新建项目,项目根目录build.gradle中配置如下信息:版本随时查看官网
buildscript {
ext.kotlin_version = '1.3.20'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//这个是用于生成宿主app的gradle插件
classpath 'com.qihoo360.replugin:replugin-host-gradle:2.2.4'
//这个是用于生成插件app的gradle插件
classpath "com.qihoo360.replugin:replugin-plugin-gradle:2.2.4"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
我们现在将app module作为宿主app,因此需要将app build.gradle做如下配置:
android {
.....
}
//启用宿主插件
apply plugin: 'replugin-host-gradle'
repluginHostConfig {
/**
* 是否使用 AppCompat 库
* 不需要个性化配置时,无需添加
*/
useAppCompat = true
/**
* 背景不透明的坑的数量
* 不需要个性化配置时,无需添加
*/
countNotTranslucentStandard = 6
countNotTranslucentSingleTop = 2
countNotTranslucentSingleTask = 3
countNotTranslucentSingleInstance = 2
}
dependencies {
//.... 其他配置
//引用relugin-host-lib 宿主
implementation 'com.qihoo360.replugin:replugin-host-lib:2.2.4'
}
此时需要配置repluginHostConfig,宿主配置,抄一下即可。但是 apply plugin: 'replugin-host-gradle'
的位置必须要在android{}
模块下面,这是Replugin必须的,至于为什么,官方wiki中描述为 防止出现无法读取applicationId,导致生成的坑位出现异常
。
然后配置Application,有两种方式:
public class MainApplication extends RePluginApplication {}
或者:
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
RePlugin.App.attachBaseContext(this);
....
}
@Override
public void onCreate() {
super.onCreate();
RePlugin.App.onCreate();
....
}
@Override
public void onLowMemory() {
super.onLowMemory();
/* Not need to be called if your application's minSdkVersion > = 14 */
RePlugin.App.onLowMemory();
....
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
/* Not need to be called if your application's minSdkVersion > = 14 */
RePlugin.App.onTrimMemory(level);
....
}
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
/* Not need to be called if your application's minSdkVersion > = 14 */
RePlugin.App.onConfigurationChanged(config);
....
}
}
build 之后,我这边报了一个错误:
No signature of method: com.android.build.gradle.internal.scope.VariantScopeImpl.getMergeAssetsTask()
is applicable for argument types: () values: []
查了资料,是说我的gradle版本存在问题,这个应该是比较尴尬的问题了,也是比较头疼的问题了。解决方案基本如下,强制规定gradle版本:
//更改gradle版本
classpath 'com.android.tools.build:gradle:3.1.4'
//gradle/wrapper/gradle-wrapper.properties 下更改distributionUrl路径
distributionUrl=https://services.gradle.org/distributions/gradle-4.4-all.zip
编译通过之后,即可安装,成为了宿主app。
我们在项目中新建一个module oneplugin作为子app,作为插件App。在oneplugin的build中需要配置一下插件。
android {
defaultConfig {
applicationId "com.xing.oneplugin"
//....
}
}
dependencies {
//.... 其他依赖
// 用于插件的replugin-plugin-lib
implementation 'com.qihoo360.replugin:replugin-plugin-lib:2.2.4'
}
//这个和宿主的不一样
//应用到插件中的
//也需要用到android{}配置下面
apply plugin: 'replugin-plugin-gradle'
//插件配置
repluginPluginConfig {
//插件名
pluginName = "plugin1"
//宿主app的包名
hostApplicationId = "com.xing.pluginlearn"
//宿主app的启动activity
hostAppLauncherActivity = "com.xing.pluginlearn.MainActivity"
}
然后将oneplugin打包apk出来
。
然后我的问题就出现这里:
我先选择了oneplugin模块,尝试使用build --> Build Bundle(s)/ APK(s) --> Build APK(s)
打包之后,但是在接下来的操作中,一直没有运行成功,后来检查中发现,原来这种打包方法,一直打的是app module的包,而我们需要oneplugin包应该怎么打呢? 有两种方法:
- 直接使用gradle命令
gradlew :oneplugin:assembleRelease
然后可以在oneplugin\build\outputs\apk\release
获取到oneplugin release版本
获取到chajianapp之后,需要将它导入手机内存卡中(这次是最简单的模式,默认从内存卡中安装),现在来修改宿主app代码:
主界面如下:
对应的三个方法分别为:
//安装插件
private fun loadPlugin() {
//安装插件
///sdcard/oneplugin-debug.apk 是插件路径
pluginInfo = RePlugin.install("/sdcard/oneplugin-debug.apk")
if(pluginInfo != null) {
//预加载插件
RePlugin.preload(pluginInfo)
Toast.makeText(this,"install success", Toast.LENGTH_LONG).show()
}else{
Toast.makeText(this, "uninstall !!!", Toast.LENGTH_LONG).show()
}
}
//启动插件
fun startActivityForPlugin(view:View) {
val intent = Intent()
//参数一: 我插件包的包名
//参数二: 我插件包里面需要启动的类
intent.component = ComponentName("com.xing.oneplugin","com.xing.oneplugin.MainActivity")
RePlugin.startActivity(this, intent)
}
// 卸载插件
fun unInstall(view:View) {
// 此处pugin1 是我定义插件包里面build.gradle repluginPluginConfig#pluginName
val result = RePlugin.uninstall("plugin1")
Log.i("TAG","uninstall result : $result" )
}
然后我们看图:
最终,我们完成了此次的插件化加载。按照教程来说并不是很难,主要是有些坑比较坑爹,这一次也初步完成了RePlugin初次探究,接下来的时间里面,我们会深入探讨一下RePlugin深层次的用法。
项目的练习地址为:https://github.com/Microhx/PluginLearn