当前位置 : 主页 > 网络编程 > 其它编程 >

AndroidGradle的神奇之处Project和Gradle插件

来源:互联网 收集:自由互联 发布时间:2023-07-02
之前AndroidGradle的神奇之处----Gradle构建和Task引入对Task任务做了简单的介绍本节着重介绍自定义Task任务之间的联动Project和G 之前Android Gradle的神奇之处 ---- Gradle构建和Task引入对Task任务做
之前AndroidGradle的神奇之处----Gradle构建和Task引入对Task任务做了简单的介绍本节着重介绍自定义Task任务之间的联动Project和G

之前Android Gradle的神奇之处 ---- Gradle构建和Task引入对Task任务做了简单的介绍本节着重介绍自定义Task任务之间的联动

Project和Gradle插件

  • 1 Task任务的输入输出
    • 1.1 Input OutputFile
    • 1.2 inputs.file outputs.files
  • 2 系统内置任务
    • 2.1 Zip
    • 2.2 packageDebug
  • 3 Task的增量构建
  • 4 Project
    • 4.1 ext属性扩展
  • 5 Gradle插件
    • 5.1 脚本插件
    • 5.2 二进制插件
      • 5.2.1 buidSrc
      • 5.2.2 buildSrc简介

1 Task任务的输入输出

通常Task任务的输入就是某个Task任务的输出例如apk打包就经过dex打包apkbuilder压缩apk签名等每个流程的输出都是下一个流程的输出在自定义Task任务中Input和OutputFile代表当前的输入和输出

1.1 Input OutputFile

class MyTask extends DefaultTask{Inputdef inputPathOutputFiledef outFileMyTask(){group customeprintln MyTask 构造方法 配置阶段执行}TaskActiondef Action(){println MyTask 执行了}}

如果在没有指定输入和输出的情况下执行task任务会报错

Type MyTask property inputPath doesnt have a configured value.

使用Optional注解代表当前属性可选可以选择不传数据就不会报错

1.2 inputs.file outputs.files

如果不想使用1.1中的注解还可以通过其他的方式给当前的task设置输入和输出

inputs.files file(build.gradle)outputs.files file(text.txt)

使用inputs.files和outputs.files可以给当前任务输入或者输出一个文件

如果想要获取输入的文件因为当前只输入一个文件可以使用singleFile获取文件内容

inputs.files.singleFile

这里进行了一个简单的读写操作将输入文件的内容复制到了输出文件中

TaskActiondef Action(){println MyTask 执行了println inputs.files.singleFiledef inFile inputs.files.singleFiledef outFile outputs.files.singleFile//创建输出文件outFile.createNewFile()//通过text直接赋值即可outFile.text inFile.text}

2 系统内置任务

2.1 Zip

Zip是系统自带的一个zip任务能够把目标文件夹的内容打成zip包发布 在这里插入图片描述

task zipTask(type: Zip){//build文件夹archiveName build.zipdestinationDir project.buildDirfrom project.buildDir}

这里有几个参数需要明确一下 from待压缩的文件所在的文件夹project.buildDir为build文件夹每个模块下都有自己的build文件夹 archiveName压缩后的文件名 destinationDir压缩后的文件存放位置

2.2 packageDebug

在app工程下build/outputs下回生成对应的 debug apk 或者 release apk如果想要获取build文件夹下的outputs文件夹需要使用packageDebug任务那么首先就要获取packageDebug任务

tasks.getByName(packageDebug)

A problem occurred evaluating project :app.> Task with name packageDebug not found in project :app.

任务是在配置阶段生成的如果直接拿是拿不到的之前讲到过的钩子函数就可以帮助在任务创建之后拿任务这个时候肯定拿的到

project.afterEvaluate{//任务配置完成之后println tasks.getByName(packageDebug)task zipTask(type: Zip){//build文件夹archiveName build.zipdestinationDir project.buildDirfrom tasks.getByName(packageDebug).outputs.files}}

在这里插入图片描述

3 Task的增量构建

当多次执行gradle脚本构建的时候第一次所有的task任务都会执行但是如果同样的task再执行一次就不会再次执行action中的操作而是默认使用上次构建的像Task B UP-TO-DATE就是没有执行

> Task :B UP-TO-DATE> Task :AA do First> Task :finalizeTask UP-TO-DATE> Task :CC do FirstC do doLast

这就是增量构建增量构建的原理就是监控input的变化只有input发送变化了才重新执行task任务否则gradle认为可以重用之前的执行结果。

4 Project

每个moudle都对应了一个project对象因通过project对象就可以对每个项目做配置

project(:app){//这里是不支持 plugins{ } 需要applyapply plugin:com.android.applicationapply plugin:kotlin-androidapply plugin:kotlin-kaptprintln("组件化")//性能上的优化def config rootProject.ext.androidIddef dependency rootProject.ext.dependencyandroid {compileSdk config.compileSdkdefaultConfig {applicationId "com.study.modulelization"minSdk config.minSdktargetSdk config.targetSdkversionCode config.versionCodeversionName config.versionNametestInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"buildConfigField("Boolean", "isRelease", "${rootProject.isRelease}")kapt {arguments{arg("moduleName","app")}}}buildTypes {debug {buildConfigField("String", "debugUrl", "\"${rootProject.url.DEBUG} \"")}release {buildConfigField("String", "releaseUrl", "\"${rootProject.url.RELEASE}\"")minifyEnabled falseproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget 1.8}}dependencies {implementation androidx.appcompat:appcompat:1.4.1implementation com.google.android.material:material:1.5.0implementation androidx.constraintlayout:constraintlayout:2.1.3implementation project(path: :complier_api2)dependency.each { k, v -> implementation v }if (rootProject.isRelease) {//依赖包implementation project(path: :register)implementation project(path: :lay_router)kapt project(path: :lay_compiler)implementation project(:complier_api2)implementation project(:commonlib)}testImplementation junit:junit:4.androidTestImplementation androidx.test.ext:junit:1.1.3androidTestImplementation androidx.test.espresso:espresso-core:3.4.0implementation androidx.lifecycle:lifecycle-runtime-ktx:2.2.0implementation androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1implementation androidx.lifecycle:lifecycle-livedata-core-ktx:2.4.1implementation org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2implementation org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2}}

这里通过project(‘模块名称’)在闭包中就可以对当前模块做配置其实这样就代替了app模块中的build.gradle

通过subprojects则是可以获取到全部的子工程的project对象

4.1 ext属性扩展

ext属性扩展其实就是对project对象做属性扩展

# ext.gradleext {prop1 prop1}

在根 build.grdle中做了属性扩展实际上就是对rootProject做了扩展那么每个子模块都能拿到这个rootProject相当于在build.grdle中声明了一个变量

# 根 build.gradleproject.ext.prop2 prop2

在子模块中去获取这个变量注意是使用rootProject

# register模块 --- build.gradleprintln rootProject.prop1println rootProject.prop2输出prop1prop2

1~ 对于所有对象都可以属性扩展通过ext{ }闭包或者直接赋值 ext.prop … 2~ 由谁调用就是给谁做扩展例如project中调用就是给project做扩展一般情况下都是 3~ 在build.gradle中默认就是给当前工程的project做扩展在根build.gradle中就是给rootProject做扩展所有的moudle都可以使用这个扩展属性

5 Gradle插件

gradle插件就是提供给gradle构建工具在编译时的依赖项主要的目的就是抽取公共的构建业务达到复用的效果

像系统提供的一些任务都是剥离出来可复用的之前常见的Zip、Clean都是插件中的任务Gradle插件共分为2种接下来讲解第一种

5.1 脚本插件

脚本插件是比较常见的一种插件在之前就已经写过一些比如抽离一个压缩zip的任务可以提供给某个模块使用

# zip.gradleproject.afterEvaluate{task zipTask(type:Zip){archiveName zip01.zipdestinationDir "${project.buildDir}/custome"from tasks.getByName(packageDebug).outputs.files}}

# app/build.gradleapply from:/****/zip.gradle

通过apply的方式就完成了脚本的注入可以执行task任务

5.2 二进制插件

二进制插件就是将脚本打成jar包实现jar包依赖

# 根 build.gradleclass MyPluginTask implements Plugin{Overridevoid apply(Project target) {println MyPluginTask apply}}

二进制插件实现了Plugin接口重写apply方法在apply方法中做业务打包使用方式还是apply只不过是使用plugin作为key

# 根 build.gradleapply plugin: MyPluginTask

像这种方式是只能在一个模块中使用这个二进制插件如果想要所有的项目共享那么就需要将这个插件上传maven私服那么在使用的时候将这个插件拉取下来使用

5.2.1 buidSrc

创建一个buildSrc文件夹注意不能写错然后重新rebuild一下工程 在这里插入图片描述 然后需要创建一个src/main/java文件夹如果使用Java编写就创建java文件夹使用groovy编写就创建groovy文件夹

public class MyTargetPlugin implements Plugin {Overridepublic void apply(Project project) {System.out.println("这是自定义的二进制插件"project.getClass());}}

当创建这个二进制插件之后就可以在任意一个moudle中使用

# register/build.gradleapply plugin: MyTargetPlugin

我们可以看到在buildSrc的libs文件夹下有一个jar包这个jar包就可以上传到maven仓库 在这里插入图片描述

5.2.2 buildSrc简介

buildSrc是Android工程默认的一个插件工程有且仅有一个能够直接实现插件的封装

settingsEvaluatedprojectsLoaded> Task :buildSrc:compileJava UP-TO-DATE> Task :buildSrc:compileGroovy NO-SOURCE> Task :buildSrc:processResources> Task :buildSrc:classes> Task :buildSrc:jar> Task :buildSrc:generateSourceRoots UP-TO-DATE> Task :buildSrc:assemble> Task :buildSrc:compileTestJava NO-SOURCE> Task :buildSrc:compileTestGroovy NO-SOURCE> Task :buildSrc:processTestResources NO-SOURCE> Task :buildSrc:testClasses UP-TO-DATE> Task :buildSrc:test SKIPPED> Task :buildSrc:check SKIPPED> Task :buildSrc:build> Configure project :资源回收MyTask 构造方法 配置阶段执行

我们可以看到在Gradle配置之前就已经在编译阶段去编译这个buildSrc项目然后配置到classpath下面那么在gradle的配置阶段就可以直接使用buildSrc中生成好的插件去做操作处理

使用buildSrc的好处在于如果要修改插件内的内容可以不用等发版就直接在本地实现配置依赖不用上传maven仓库例如在插件中创建一个zip任务不需要发版在app模块中直接依赖即可

public class MyTargetPlugin implements Plugin {Overridepublic void apply(Project project) {System.out.println("这是自定义的二进制插件"project.getClass());project.afterEvaluate(new Action() {Overridepublic void execute(Project project) {File buildDir project.getBuildDir();Task packageDebug project.getTasks().getByName("packageDebug");Map map new HashMap();map.put("type", Zip.class);//Java 创建taskZip zipTask (Zip) project.task(map,"pluginTask");//设置输入输出zipTask.setArchiveName("zip02.zip");zipTask.setDestinationDir(new File(buildDir.getAbsolutePath()));zipTask.from(packageDebug.getOutputs().getFiles());}});}}

通过Java也可以实现在gradle中创建zip任务的流程就是写起来比较繁琐 在这里插入图片描述

# app/build.gradleapply plugin: MyTargetPlugin【文章原创作者:韩国机房 http://www.558idc.com/kt.html欢迎留下您的宝贵建议】

上一篇:django没有列-Columndoesnotexistindjango1.6.5
下一篇:没有了
网友评论