最近项目代码中有涉及插件的一些功能需求,所以打算自己先练习下RePlugin插件化的相关功能。
首先:RePlugin官方地址,可以去看下官方的文档和示例代码(示例代码可能在自己本地Android Studio上跑不了,是需要修改一些配置文件):
app下的build.gradle文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '29.0.1'
defaultConfig {
applicationId "com.qihoo360.replugin.sample.host"
minSdkVersion 16
//noinspection ExpiredTargetSdkVersion
targetSdkVersion 26
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
apply plugin: 'replugin-host-gradle'
/**
* 配置项均为可选配置,默认无需添加
* 更多可选配置项参见replugin-host-gradle的RepluginConfig类
* 可更改配置项参见 自动生成RePluginHostConfig.java
*/
repluginHostConfig {
/**
* 是否使用 AppCompat 库
* 不需要个性化配置时,无需添加
*/
useAppCompat = true
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'com.qihoo360.replugin:replugin-host-lib:2.3.4'
}
项目的build.gradle文件
buildscript {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
dependencies {
classpath 'com.qihoo360.replugin:replugin-host-gradle:2.3.4'
classpath 'com.android.tools.build:gradle:3.4.1'
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
上面两个build文件根据自己的实际情况进行配置后,可以在本地运行官网的示例代码。
本地新建一个项目
项目的build文件
plugins {
id 'com.android.application' version '7.4.1' apply false
id 'com.android.library' version '7.4.1' apply false
}
项目的settings文件
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "RePluginDemo"
include ':app'
主程序接入指南(打不开的多开几次,或者科技上网)
applicationId后面跟着的是自己项目的包路径
在项目的build文件中配置的时候,settings文件需要进行修改(其余内容删掉):
rootProject.name = "RePluginDemo"
include ':app'
文件中只保留上述两行代码就行。
然后配置项目的build文件:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
dependencies {
classpath 'com.qihoo360.replugin:replugin-host-gradle:2.2.4'
classpath 'com.android.tools.build:gradle:3.4.1'
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
classpath后面的版本根据自己的情况来配置
app下的build文件配置(这个是我根据自己本地情况进行的配置,配置的过程中会出现各种问题。)
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '29.0.1'
defaultConfig {
applicationId "com.plugin"
minSdkVersion 16
//noinspection ExpiredTargetSdkVersion
targetSdkVersion 26
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
//ATTENTION!!! Must be PLACED AFTER "android{}" to read the applicationId
apply plugin: 'replugin-host-gradle'
/**
* 配置项均为可选配置,默认无需添加
* 更多可选配置项参见replugin-host-gradle的RepluginConfig类
* 可更改配置项参见 自动生成RePluginHostConfig.java
*/
repluginHostConfig {
/**
* 是否使用 AppCompat 库
* 不需要个性化配置时,无需添加
*/
useAppCompat = true
}
configurations.all {
resolutionStrategy.eachDependency {
DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == "androidx.appcompat") {
if (requested.name == "appcompat") {
details.useVersion "1.3.1"
}
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.qihoo360.replugin:replugin-host-lib:2.3.4'
implementation 'com.android.support:support-v4:30.4.1' // 报错不要管
}
gradle.properties文件中添加的配置
android.useAndroidX=true
android.enableJetifier=true
gradle-wrapper.properties文件配置
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
AndroidManifest.xml配置
只需要在application
标签中添加android:name=".MainAppComActivity"
就可以,MainAppComActivity
是我自己创建的类,只要继承RePluginApplication
就可以了。
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.qihoo360.replugin.RePluginApplication;
import com.qihoo360.replugin.RePluginCallbacks;
import com.qihoo360.replugin.RePluginConfig;
import com.qihoo360.replugin.RePluginEventCallbacks;
public class MainAppComActivity extends RePluginApplication {
// ----------
// 自定义行为
// ----------
/**
* RePlugin允许提供各种“自定义”的行为,让您“无需修改源代码”,即可实现相应的功能
*/
@Override
protected RePluginConfig createConfig() {
RePluginConfig c = new RePluginConfig();
// 允许“插件使用宿主类”。默认为“关闭”
c.setUseHostClassIfNotFound(true);
// FIXME RePlugin默认会对安装的外置插件进行签名校验,这里先关掉,避免调试时出现签名错误
c.setVerifySign(!BuildConfig.DEBUG);
// 针对“安装失败”等情况来做进一步的事件处理
c.setEventCallbacks(new HostEventCallbacks(this));
// FIXME 若宿主为Release,则此处应加上您认为"合法"的插件的签名,例如,可以写上"宿主"自己的。
// RePlugin.addCertSignature("AAAAAAAAA");
// 在Art上,优化第一次loadDex的速度
// c.setOptimizeArtLoadDex(true);
return c;
}
@Override
protected RePluginCallbacks createCallbacks() {
return new HostCallbacks(this);
}
/**
* 宿主针对RePlugin的自定义行为
*/
private class HostCallbacks extends RePluginCallbacks {
private static final String TAG = "HostCallbacks";
private HostCallbacks(Context context) {
super(context);
}
@Override
public boolean onPluginNotExistsForActivity(Context context, String plugin, Intent intent, int process) {
// FIXME 当插件"没有安装"时触发此逻辑,可打开您的"下载对话框"并开始下载。
// FIXME 其中"intent"需传递到"对话框"内,这样可在下载完成后,打开这个插件的Activity
if (BuildConfig.DEBUG) {
Log.d(TAG, "onPluginNotExistsForActivity: Start download... p=" + plugin + "; i=" + intent);
}
return super.onPluginNotExistsForActivity(context, plugin, intent, process);
}
}
private class HostEventCallbacks extends RePluginEventCallbacks {
private static final String TAG = "HostEventCallbacks";
public HostEventCallbacks(Context context) {
super(context);
}
@Override
public void onInstallPluginFailed(String path, InstallResult code) {
// FIXME 当插件安装失败时触发此逻辑。您可以在此处做“打点统计”,也可以针对安装失败情况做“特殊处理”
// 大部分可以通过RePlugin.install的返回值来判断是否成功
if (BuildConfig.DEBUG) {
Log.d(TAG, "onInstallPluginFailed: Failed! path=" + path + "; r=" + code);
}
super.onInstallPluginFailed(path, code);
}
@Override
public void onStartActivityCompleted(String plugin, String activity, boolean result) {
// FIXME 当打开Activity成功时触发此逻辑,可在这里做一些APM、打点统计等相关工作
super.onStartActivityCompleted(plugin, activity, result);
}
}
}
以上配置好之后起码主项目可以正常运行,后面的就是插件项目的配置!!!