Android gradle 构建

Understanding Tasks  - Gradle task

kapt  是 Kotlin 语言的注解处理器,它是 Android Studio 中用于处理 Kotlin 注解的工具。它通过在编译期间生成代码来增强 Kotlin 代码的功能。需要 Kotlin 编译器来解析和处理注解;使用 APT 来生成代码,它是一个独立的工具,用于处理 Java 注解
依赖注入:类通常需要引用其他类。例,Car 类可能需要引用 Engine 类。这些必需的类称为依赖项,在此示例中,Car 类必须拥有 Engine 类的一个实例才能运行。

以参数形式提供。应用可以在构造类时提供这些依赖项,或者将这些依赖项传入需要各个依赖项的函数。在上面的示例中,Car 构造函数将接收 Engine 作为参数。构造函数注入 && 字段注入

https://developer.android.com/training/dependency-injection?hl=zh-cn

 Hilt 依赖注入框架

模块/组件间注入依赖

https://developer.android.com/training/dependency-injection/hilt-android?hl=zh-cn

tasks.namedtask myTask = tasks.named("myTaskName")从人物列表中返回myTaskName

tasks.register("qualityCheck") {

向构建脚本中注册任务(name,tasktype)

Tasks.register<Zip>("packageApp") {

} 构建内置或自定义任务的实例

Gradle 分为两类任务

Lifecycle tasks生命周期任务

Actionable tasks 可操作任务,连接到生命周期

gradle工程构建的生命周期

Build Lifecycle

自定义任务可以分配配置阶段

执行阶段:开始执行,结束执行阶段

执行期间是表示TaskAction执行

setting.kts:初始化阶段

build.gradle.kts: 配置阶段,以下demo中task.register是在配置阶段执行,所以里面的println也在配置阶段执行

执行阶段:dofirst{} dolast{}

Gradle基础任务类型 

Task的子类, Zip, Copy, or Delete

Copy: 用于复制文件和目录。
Jar: 用于创建 JAR 文件。
War: 用于创建 WAR 文件。
Test: 用于运行测试。
Clean: 用于清理构建目录。
... 等等

自定义任务类型DefaultTask

Writing Tasks

Registering a task - using a task (implemented by you or provided by Gradle) in your build logic.
注册任务 - 在构建逻辑中使用任务(由您实现或由 Gradle 提供)。

Configuring a task - defining inputs and outputs for a registered task.
配置任务 - 定义已注册任务的输入和输出。

Implementing a task - creating a custom task class (i.e., custom class type).
实现任务 - 创建自定义任务类(即自定义类类型)。

 public abstract class GenerateReportTask : DefaultTask() {//声明自定义类型

    @get:InputDirectory    //自定义任务输入sourceDirectory
    lateinit var sourceDirectory: File

    @get:OutputFile         //自定义任务输出
    lateinit var reportFile: File

    @TaskAction    //任务操作的具体逻辑

    fun generateReport() {}

}

tasks.register<GenerateReportTask>("generateReport") {
    sourceDirectory = file("src/main")
    reportFile = file("${layout.buildDirectory}/reports/directoryReport.txt")
}

tasks.build {
    dependsOn("generateReport")
}

任务配置(传参)

1.named

2.register+配置块

build.gradle.kts
tasks.named<Copy>("myCopy") {
    from("resources")
    into("target")
    include("**/*.txt", "**/*.xml", "**/*.properties")
}

自定义任务-不定义任务类型DefaultTask

Advanced Tasks

tasks.register("printVersionDynamic") {
    inputs.property("version", project.version.toString())  //声明变量
    doLast {
        println("Version: ${inputs.properties["version"]}") //向doLast注入任务回调
    }
}
可操作任务链接到生命周期tasks.build { //build生命周期任务依赖packageApp任务,所以会先执行packageApp
    dependsOn(packageApp)
}
查看任务./gradlew :app:tasks

Android gradle 配置集合(kts迁移)

https://developer.android.com/build?hl=zh-cn

编写Android插件,对已有构建流程扩展修改https://developer.android.com/build/extend-agp?hl=zh-cn
Android依赖问题及冲突解决

aar打包、发布到maven、带第三方依赖的打包、带本地module依赖的打包_aar打包第三方依赖库-CSDN博客

https://juejin.cn/post/7186908438058762277

Android kts引用其他构建脚本

apply { from("library.gradle") } 

includeBuild("library.gradle")

gradle插件和gralde版本不匹配问题:
com.android.tools.build:gradle和gradle-wrapper.properties

彻底解决Android Studio Minimum supported Gradle version is X.Y.Z. Current version is x.y.z.问题_minimum supported gradle version is 6.7.1. current-CSDN博客

https://developer.android.com/build/releases/gradle-plugin?hl=zh-cn#updating-gradle

自定义例子:

tasks.register("buildAll") {
    dependsOn(":app:assembleDebug", ":app:assembleRelease")
    doFirst {
        println("Building debug and release variants...")
    }
    doLast {
        println("Finished building both variants!")
    }
}

  1. task buildAll(type: Exec): 定义一个名为 buildAll 的自定义任务,类型为 Exec (表示执行命令)。
  2. dependsOn ":app:assembleDebug", ":app:assembleRelease": 声明 buildAll 任务依赖于 :app:assembleDebug 和 :app:assembleRelease 任务。这意味着 buildAll 任务会在它们完成后执行。
  3. doFirst { ... }: 在 buildAll 任务执行之前执行的代码块,可以用来输出信息或执行其他操作。
  4. doLast { ... }: 在 buildAll 任务执行之后执行的代码块,同样可以用来输出信息或执行其他操作
tasks.getByName("xxx") 获取模块中的gradle任务
读取.property 文件属性android - Read value from local.properties via Kotlin DSL - Stack Overflow
android.testVariants获取测试变体(assembleDebugAndroidTest)
libraryVariants获取模块变体(debug,release)
Android fix 依赖项冲突https://developer.android.com/build/dependency-resolution-errors?hl=zh-cn
解决依赖冲突,冲突时强制使用某个版本或者在引入冲突时排除

configurations.all {
    resolutionStrategy.force 'org.somelibrary:library-core:1.2'
}

或者引入排除

testCompile('com.squareup.assertj:assertj-android:1.0.0') {
     exclude group: 'com.android.support', module: 'support-annotations'
 }

构建报错@error.NonExistentClass()kapt {
    correctErrorTypes true 
Android Native构建配置,sourceset JNILib指定打包的库https://developer.android.com/studio/projects/gradle-external-native-builds
Android cmakehttps://developer.android.com/ndk/guides/cmake?hl=zh-cn
Dynamic Feature Module

https://juejin.cn/post/7049522872682807333

Android App Bundle官方插件模式

Gradle中如果想要对子模块的构建产物进行过滤或重命名等操作,需要如何书写?

如何在project下获取子模块的gradle任务并修改?


在 Gradle 中,你可以通过以下几种方式对子模块的构建产物进行过滤或重命名,以及在 Project 级获取子模块的 Gradle 任务并修改:

1. 使用 configurations 过滤构建产物

场景: 你只想将子模块中的特定类型的文件包含到主项目的构建产物中。

实现: 在主项目的 build.gradle 中,使用 configurations 属性来配置依赖项,并使用 include 或 exclude 来过滤特定文件。

dependencies {  
    implementation project(":submodule") // 依赖子模块  
    // 仅包含子模块中的 'jar' 文件  
    implementation(project(":submodule"), {  
        include("*.jar")  
    })  
    // 排除子模块中的 'test' 文件夹下的所有文件  
    implementation(project(":submodule"), {  
        exclude("**/*.test")  
    })  
}  
2. 使用 transform 转换构建产物

场景: 你需要对子模块的构建产物进行转换,例如压缩、重命名、加密等。

实现: 在主项目的 build.gradle 中,定义一个 Transform 任务,并在 transform 方法中对输入文件进行操作。

tasks.register("transformSubmodule") {  
    doLast {  
        // 获取子模块的构建产物路径  
        val submoduleOutputDir = file("${project(":submodule").buildDir}/libs")  

        // 遍历子模块的构建产物,并进行转换操作  
        submoduleOutputDir.listFiles().forEach { file ->  
            // 对 file 进行转换操作  
        }  
    }  
}  

// 在主项目的构建生命周期中执行 "transformSubmodule" 任务  
tasks.named("assembleRelease").configure {  
    dependsOn(tasks.named("transformSubmodule"))  
}  
3. 使用 afterEvaluate 获取子模块的 Gradle 任务并修改

场景: 你需要对子模块的 Gradle 任务进行修改,例如添加依赖、修改参数等。

实现: 在主项目的 build.gradle 中,使用 afterEvaluate 闭包来获取子模块的 Gradle 任务,然后进行修改。

afterEvaluate {  
    // 获取子模块的 "assembleRelease" 任务  
    val submoduleAssembleRelease = project(":submodule").tasks.named("assembleRelease")  

    // 修改子模块的 "assembleRelease" 任务  
    submoduleAssembleRelease.configure {  
        // 添加依赖  
        dependsOn(tasks.named("myTask"))   
        // 修改参数  
        doFirst {  
            // ...  
        }  
    }  
}  
4. 使用 project 获取子模块的 Gradle 任务并修改

场景: 你需要在主项目的构建生命周期中获取子模块的 Gradle 任务并进行修改。

实现: 在主项目的 build.gradle 中,使用 project 获取子模块的 Task 对象,然后进行修改。

// 获取子模块的 "assembleRelease" 任务  
val submoduleAssembleRelease = project(":submodule").tasks.named("assembleRelease")  

// 修改子模块的 "assembleRelease" 任务  
submoduleAssembleRelease.configure {  
    // 添加依赖  
    dependsOn(tasks.named("myTask"))   
    // 修改参数  
    doFirst {  
        // ...  
    }  
}  
一些注意事项:

确保在主项目的 build.gradle 中正确配置子模块的依赖关系。
使用 afterEvaluate 或 project 获取子模块的 Gradle 任务时,需要确保子模块的构建已经完成。
在进行任务修改操作时,需要注意依赖关系和执行顺序。
以上几种方法可以帮助你实现对子模块构建产物的过滤、重命名以及对子模块 Gradle 任务的修改。根据具体需求选择适合的方法进行操作。

要在Kts文件中修改gradle任务publishAllPublicationsToMyRepository,使其中某个产物不推送到远程仓库,可以通过如下方式处理:

  1. 找到该任务的定义,通常是在Kts文件中指定发布构建产物到远程仓库的方式,类似如下代码:

publishing { repositories { maven { url = uri("https://myrepo") } } } tasks.register("publishAllPublicationsToMyRepository") { dependsOn(tasks.withType<PublishToMavenPublication>()) }

  1. 在该任务中使用onlyIf方法来判断某个产物,然后在publish方法中设置exclude规则,将不需要发布的产物排除掉,类似如下代码:

tasks.register("publishAllPublicationsToMyRepository") { dependsOn(tasks.withType<PublishToMavenPublication>()) onlyIf { // 判断需要发布的产物 true // 返回需要发布的条件 } doLast { // 获取需要发布的产物 val publications = project.tasks.withType<PublishToMavenPublication>().filter { // 过滤出需要发布的产物 } // 设置不需要发布的产物 publications.forEach { publication -> publication.publish { exclude("**/exclude-artifact.jar") } } } }

  1. 在代码中替换exclude-artifact.jar为你需要排除的产物的名称。然后运行gradle任务publishAllPublicationsToMyRepository,就可以实现只推送部分构建产物到远程仓库的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值