360 RePlugin 初探

Posted microhex

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了360 RePlugin 初探相关的知识,希望对你有一定的参考价值。

大概

在项目整合的过程中,要使用到插件化,听说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

我们现在将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。

插件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安装一下,得到如下图:

然后将oneplugin打包apk出来
然后我的问题就出现这里:

我先选择了oneplugin模块,尝试使用build --> Build Bundle(s)/ APK(s) --> Build APK(s) 打包之后,但是在接下来的操作中,一直没有运行成功,后来检查中发现,原来这种打包方法,一直打的是app module的包,而我们需要oneplugin包应该怎么打呢? 有两种方法:

  1. 直接使用gradle命令
    gradlew :oneplugin:assembleRelease
    然后可以在oneplugin\\build\\outputs\\apk\\release 获取到oneplugin release版本
  1. 选择Build Variants 选择release版本,然后点击运行,其实可以在相同的路径下找到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

以上是关于360 RePlugin 初探的主要内容,如果未能解决你的问题,请参考以下文章

Replugin 源码分析------replugin-host-gradle插件源码分析

Replugin 源码分析------replugin-plugin-gradle插件源码分析

Replugin 源码分析------replugin-plugin-gradle插件源码分析

360手机卫士插件化RePlugin今日开源

Replugin 浅谈

唯一插件化RePlugin源码及原理深度剖析--工程职责及大纲