Plugin 的写法
1. 写在 build.gradle
中
代码语言:javascript复制build.gradle
tips:单个项目使用, 进行一些简单任务, 不方便进行复用
class PluginDemo implements Plugin<Project> {
@Override
void apply(Project target) {
println 'Hello word!'
} }
apply plugin: PluginDemo
or
class ExtensionDemo {
def name = 'dalong'
}
class PluginDemo implements Plugin<Project> {
@Override
void apply(Project target) {
def extension = target.extensions.create('mplugin', ExtensionDemo)
target.afterEvaluate {
println "Hello ${extension.name}!"
}
} }
apply plugin: PluginDemo
mplugin {
name 'dalong1111'
}
2. 写在 buildSrc ⽬录下
tips:单个项目使用, 进行了代码分离,可以进行一定程度的复用
- 目录结构:
*.properties
resources
目录是固定写法,可以包含多个*.properties
文件。 其中*
为plugin
的名称。 例如:mdemo.properties
,mdemo
为pluge
的名称,使用时如下引用:
apply plugin: 'mdemo'
*.properties
内容如下:
implementation-class=com.tencent.demo.PluginDemo
com.tencent.demo.PluginDemo
是实现类Plugin
接口的具体类
- groovy目录
代码语言:javascript复制PluginDemo.groovy
class PluginDemo implements Plugin<Project> {
@Override
public void apply(Project project) {
def extension = project.extensions.create('mplugin', ExtensionDemo)
project.afterEvaluate {
println "Hello ${extension.name}!"
}
}
}
代码语言:javascript复制ExtensionDemo.groovy
class ExtensionDemo {
def name = "dalong"
}
- 关于buildSrc
- 这是
gradle
的⼀个特殊目录,这个目录的build.gradle
会自动被执⾏,不需再配置到settings.gradle
-
buildSrc
的执⾏早于任何⼀个project
,也早于settings.gradle
-
buildSrc
中配置的plugin
,会被添加到settings.gradle
中的所有子project
中classpath
中, 因此所有的project 可以使用apply plugin: '***'
来使用自定义的plugin
- 这是
build.gradle
官网参考: https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources
代码语言:javascript复制buildSrc/build.gradle
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.12'
}
or
apply plugin: 'groovy'
dependencies {
implementation gradleApi() //gradle sdk
implementation localGroovy() //groovy sdk
}
3. 独立第三方组件
和创建model工程一样创建一个plugin的model工程。
- build.gradle 配置如下
apply plugin: 'groovy'
apply plugin: 'maven'
allprojects {
repositories {
maven { url 'http://maven.oa.com/nexus/content/repositories/android' }
maven { url 'http://maven.oa.com/nexus/content/repositories/thirdparty/' }
mavenLocal()
}
}
dependencies {
implementation gradleApi()
implementation localGroovy()
}
// plugin 发布到本地仓库
group = 'mdemo'
version="1.0.0"
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
- setting.gradle 中需要 include , 新创建的plugin的model工程
- 工程根目录下build.gradle 配置
project.version="1.0.0"
buildscript {
repositories {
maven {
url './repo'
}
maven { url "******" }
mavenLocal()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'mdemo:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url "******" }
mavenLocal()
}
}
关于Plugin 的一个Demo
目标
: 通过Plugin 的方式,配置应用程序的反调试检测
关键实现:
- 1、通过第三种方式添加plugin插件工程(plugin开发完后发布在本地,在app工程中引入)
- 2、在plugin中,通过config配置控制行为,添加task的方式来
代码语言:javascript复制添加自定义config配置( app model 中 build.gradle )
....
....
apply plugin: 'anti-debug-plugin'
MDebugInfo {
debug {
checkJavaDebuggableInterval 60
checkJavaDebuggable true
}
release {
checkJavaDebuggableInterval 60
checkJavaDebuggable true
}
}
dependencies {
...
...
}
代码语言:javascript复制groovy 中 plugin 的实现
public class MDebugPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.extensions.create("MDebugInfo", MDebugInfoExtension);
project.MDebugInfo.extensions.create("debug", DebugBuildConfig);
project.MDebugInfo.extensions.create("release", ReleaseBuildConfig);
// 创建 task 任务
project.tasks.create(name: "genMDebugSoDebug", type: GenMDebugSoDebug, dependsOn: ["preBuild"]);
project.tasks.create(name: "genMDebugSoRelease", type: GenMDebugSoRelease, dependsOn: ["preBuild"]);
// 设置task执行时机
project.tasks.whenTaskAdded { theTask ->
if (theTask.name.equals("transformNativeLibsWithStripDebugSymbolForRelease")) {
theTask.dependsOn "genMDebugSoRelease"
}
if (theTask.name.equals("transformNativeLibsWithStripDebugSymbolForDebug")) {
theTask.dependsOn "genMDebugSoDebug"
}
}
}
}
代码语言:javascript复制groovy 中 plugin 的实现
GenMDebugSoDebug、GenMDebugSoRelease
task 任务中通过NDK来编译so文件
// 调用函数
String jniDir = project.android.sourceSets.main.jniLibs.srcDirs[0];
genMDebugSo(MConfig, "${project.buildDir}", "${project.rootProject.projectDir}", jniDir, true);
task 实现函数
public void genMDebugSo(BuildConfig buildConfig, String buildPath, String rootPath, String jniDir, boolean isRelease) {
//1 创建jni临时目录
String jniTmpPath = buildPath "/jniTmp/jni";
File jniTmpFile = new File(jniTmpPath);
if (!jniTmpFile.exists()) {
jniTmpFile.mkdirs();
}
//2 拷贝jni相关文件
copyFile(jniTmpPath, "/jni", "Android.mk");
copyFile(jniTmpPath, "/jni", "Application.mk");
copyFile(jniTmpPath, "/jni", "MDebug.cpp");
copyFile(jniTmpPath, "/jni", "JNIModel.h");
String ndkPath = System.getenv("ANDROID_NDK_HOME");
if (ndkPath == null) {
Properties properties = new Properties();
File localFile = new File(rootPath "/" "local.properties");
properties.load(new InputStreamReader(new FileInputStream(localFile)));
ndkPath = properties.getProperty("ndk.dir")
}
println "ndk.dir: " ndkPath "n";
println "jniDir: " jniDir "n";
File jniSoDir = new File(jniDir File.separator "armeabi");
jniSoDir.mkdirs();
if (!ndkPath.endsWith(File.separator)){
ndkPath = File.separator;
}
int checkJavaDebuggerInterval = buildConfig.checkJavaDebuggableInterval;
boolean checkJavaDebugger = buildConfig.checkJavaDebuggable;
String argvs = " .......“;
print "argvs " argvs "n";
//编译so
String cmdStr= ndkPath "ndk-build " argvs " NDK_PROJECT_PATH=" buildPath "/jniTmp APP_BUILD_SCRIPT=" jniTmpPath "/Android.mk";
println cmdStr "n";
Process process = Runtime.getRuntime().exec(cmdStr);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line = reader.readLine())!= null){
println "ndk-build info: " line;
}
reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while((line = reader.readLine())!= null){
println "ndk-build err: " line;
}
process.waitFor();
//5 拷贝so
String outPath = jniSoDir.getAbsoluteFile();
(new AntBuilder()).copy(file: buildPath "/jniTmp/libs/armeabi/libad.so", tofile: outPath "/libad.so");
println "copy " buildPath "/jniTmp/libs/armeabi/libad.so to " outPath "/libad.so";
}
- 3、通过 plugin的方式,添加对应的功能so会编译早app中的jni目录。 这样在app build 或者 run 的时候就可以使用这个功能了。
End!