Android使用RePlugin插件化的过程及问题解决

前言

最近项目代码中有涉及插件的一些功能需求,所以打算自己先练习下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);
        }
    }
}

以上配置好之后起码主项目可以正常运行,后面的就是插件项目的配置!!!

猜你喜欢

转载自blog.csdn.net/jxj960417/article/details/130399869
今日推荐