Android RePlugin 使用及源码分析(1)

1. RePlugin 概述

RePlugin是一套完整的、稳定的、适合全面使用的,占坑类插件化方案。
具体来说有如下特点:
完整的:让插件运行起来“像单品那样”,支持大部分特性
稳定的:如此灵活完整的情况下,其框架崩溃率仅为业内很低的“万分之一”
适合全面使用的:其目的是让应用内的“所有功能皆为插件”
占坑类:以稳定为前提的Manifest占坑思路
插件化方案:基于Android原生API和语言来开发,充分利用原生特性

作为一款成熟的插件化框架,官方列举了RePlugin如下优势:

极其灵活:主程序无需升级(无需在Manifest中预埋组件),即可支持新增的四大组件,甚至全新的插件
**非常稳定:**Hook点仅有一处(ClassLoader),无任何Binder Hook!如此可做到其崩溃率仅为“万分之一”,并完美兼容市面上近乎所有的Android ROM
特性丰富:支持近乎所有在“单品”开发时的特性。包括静态Receiver、Task-Affinity坑位、自定义Theme、进程坑位、AppCompat、DataBinding等
易于集成:无论插件还是主程序,只需“数行”就能完成接入
管理成熟:拥有成熟稳定的“插件管理方案”,支持插件安装、升级、卸载、版本管理,甚至包括进程通讯、协议版本、安全校验等
数亿支撑:有360手机卫士庞大的数亿用户做支撑,三年多的残酷验证,确保App用到的方案是最稳定、最适合使用的

RePlugin 项目一共4个库,其中有两个是library库,两个是gradle插件工程,工程截图如下:
这里写图片描述

1. replugin-host-gradle
host工程使用的Gradle插件,主要功能是宿主程序打包的过程中动态的修改AndroidManifest.xml的信息,动态的生成占位各种Activity、provider和service的声明。

2. replugin-host-library
宿主工程的library,RePlugin 的核心功能都在这个库中,RePlugin 框架的初始化,插件的安装,加载以及启动都与这个库有很大关系。

3. replugin-plugin-gradle
插件工程的Gradle的插件,替换插件工程中的Activity的继承全部替换成Replugin库中定义的XXXActivity。动态的将插件apk中调用LocalBroadcastManager的地方修改为Replugin中的PluginLocalBroadcastManager调用,动态修改ContentResolver和ContentProviderClient的调用修改成Replugin调用,动态的修改插件工程中所有调用Resource.getIdentifier方法的地方,将第三参数修改为插件工程的包名 。

4. replugin-plugin-library
插件工程的library,通过反射的方式来使用宿主程序中接口和功能。

2. 如何集成 RePlugin

RePlugin 对插件的管理有两种方式:内置插件和外置插件
外置插件是指可通过“下载”、“放入SD卡”等方式来安装并运行的插件。
内置插件是指可以“随着主程序发版”而下发的插件,通常这个插件会放到主程序的Assets目录下。
大多数情况使用插件都是外置的方式,所以接下来我们就以外置的方式来梳理RePlugin的集成方式。

要将 RePlugin 集成到我们自己的项目中,需要分别在宿主工程和插件工程分别集成RePlguin框架:

宿主集成 RePlguin:
  • 1 . 添加 RePlugin Host Gradle 依赖
    在工程项目根目录的 build.gradle(注意:不是 app/build.gradle) 中添加 replugin-host-gradle 依赖:
buildscript {
    dependencies {
        classpath 'com.qihoo360.replugin:replugin-host-gradle:2.2.4'
        ...
    }
}
  • 2 . 添加 RePlugin Host Library 依赖
    在 app/build.gradle 中应用 replugin-host-gradle 插件,并添加 replugin-host-lib 依赖:
apply plugin: 'replugin-host-gradle'
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
    implementation 'com.qihoo360.replugin:replugin-host-lib:2.2.4'
}

注意:请将apply plugin: ‘replugin-host-gradle’放在 android{} 块之后,防止出现无法读取applicationId,导致生成的坑位出现异常

  • 3 . 配置 Application 类
    这里有两种做法,最简单的方式就是让宿主工程的 Application 直接继承自 RePluginApplication。
    如果工程本身没有Application,那就直接继承RePluginApplication,如下:
public class App extends RePluginApplication {
    ...
}

然后在AndroidManifest中配置这个App

<application
    android:name=".MainApplication"
... />

当宿主功能已经定义了Application,那此时就直接找到它的基类的,该基类必然是继承自Application,此时我们只需要让该基类继承RePluginApplication即可。

上面的方法无论怎么都是采用继承的方式来做的,如果实在不想继承,还可以在已有的Application中的相应生命周期函数中调用RePlugin的方法:

RePlugin.App.attachBaseContext(this);
RePlugin.App.onCreate();
RePlugin.App.onLowMemory();
RePlugin.App.onTrimMemory(level);
RePlugin.App.onConfigurationChanged(config);
插件集成 RePlguin:
  • 1 . 添加 RePlugin Plugin Gradle 依赖
    在工程项目根目录的 build.gradle(注意:不是 app/build.gradle) 中添加 replugin-plugin-gradle 依赖:
buildscript {
    dependencies {
        classpath 'com.qihoo360.replugin:replugin-plugin-gradle:2.2.4'
        ...
    }
}
  • 2 .添加 RePlugin Plugin Library 依赖
    在 app/build.gradle 中应用 replugin-plugin-gradle 插件,并添加 replugin-plugin-lib 依赖:
apply plugin: 'replugin-plugin-gradle'
dependencies {
    compile 'com.qihoo360.replugin:replugin-plugin-lib:2.2.4'
    ...
}

经过以上操作,宿主和插件的RePlguin框架就算集成完成了,接下来就是如何去在项目中使用了。

3. 使用 RePlugin

对于插件App经过上面的集成步骤后就可以直接打包在宿主工程中使用了,但怎么使用呢? 拿外置集成来说,我们只需要将打包好的插件APK放置在手机特定目录下,这里我们选择放在SD卡的根目录下,然后在host宿主工程中调用RePlugin 的API去安装该插件APK就行,安装成功后就可以直接启动插件了,具体做法如下:
1. 首先打包插件APK,pluginApp.apk, 将该APK放置在SD卡根目录下;
2. 在宿主工程中安装插件APK pluginApp.apk, 完整的安装过程代码如下:

private void installPlugin() {
    //判断插件是否已经安装,插件的名字为插件的包名com.example.pluginapp
    PluginInfo info = MP.getPlugin("com.example.pluginapp", true);
    if (info == null) {
        //插件apk 位于sd卡根目录下
        String path = Environment.getExternalStorageDirectory().getPath() + "/pluginApp.apk";
        //判断插件apk文件是否存在
        File pluginApk = new File(path);
        if (pluginApk.exists()) {
            PluginInfo pluginInfo = RePlugin.install(path);
            if (pluginInfo == null) {
                Toast.makeText(this, "插件安装失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "插件安装成功", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(this, "sd卡路径下无插件apk", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(this, "插件已经安装", Toast.LENGTH_SHORT).show();
    }
}

3 .如果安装成功,接下来就可以直接启动插件了,代码如下:

private void setupPlugin() {
    Intent intent = RePlugin.createIntent("com.example.pluginapp", "com.example.pluginapp.MainActivity");
    RePlugin.startActivity(MainActivity.this, intent);
}  

其实创建Intent的操作可以不使用RePlugin提供的接口,用Android 原生的方式也是可以的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值