build.gradle
中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'
}
tips:单个项目使用, 进行了代码分离,可以进行一定程度的复用
*.properties
resources
目录是固定写法,可以包含多个 *.properties
文件。 其中 *
为plugin
的名称。
例如: mdemo.properties
, mdemo
为pluge
的名称,使用时如下引用:apply plugin: 'mdemo'
*.properties
内容如下:
implementation-class=com.tencent.demo.PluginDemo
com.tencent.demo.PluginDemo
是实现类Plugin
接口的具体类
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}!"
}
}
}
ExtensionDemo.groovy
class ExtensionDemo {
def name = "dalong"
}
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_sourcesbuildSrc/build.gradle
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.12'
}
or
apply plugin: 'groovy'
dependencies {
implementation gradleApi() //gradle sdk
implementation localGroovy() //groovy sdk
}
和创建model工程一样创建一个plugin的model工程。
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'))
}
}
}
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 的方式,配置应用程序的反调试检测
添加自定义config配置( app model 中 build.gradle )
....
....
apply plugin: 'anti-debug-plugin'
MDebugInfo {
debug {
checkJavaDebuggableInterval 60
checkJavaDebuggable true
}
release {
checkJavaDebuggableInterval 60
checkJavaDebuggable true
}
}
dependencies {
...
...
}
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"
}
}
}
}
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";
}
End!