Android 开发之Gradle基础

Android Studio工程的项目结构

Android Studio作为专业的安卓开发工具,它在构建安卓项目的时候具有很大的优势,首先了解安卓的项目结构对开发非常重要,直接上图:
Android Studio生成的项目结构
其实,一个完整的Android Studio工程我们可以分为5个部分,图中选出的是日常经常开发关注的部分,他们分别是:

  • app模块:他是Android项目的核心模块,项目的核心功能与主要业务在该模块下开发,build文件夹存放编译生成的文件,build.gradle是该模块的构建脚本
  • 图中第2部分:整个项目的构建脚本(build.gradle)、项目的基础配置信息(settings.gradle)、执行脚本与一些配置文件,重点关注build.gradle
  • 图中第3部分:Gradle的版本以及缓存路径的配置信息
  • 图中第4部分:项目的子Module,结构与app类似

Gradle简介

Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置。

Gradle可以使用groovy或者Kotlin语言进行脚本开发,目前主要使用Groovy语言,Groovy语法此处不过多叙述,关注闭包以及他的动态特性即可。

安装教程以及其它内容可自行科学上网~~

Gradle的task ——任务

task是gardle中最小的任务单元,任务之间可以进行复杂的操作(如动态创建任务,多任务间依赖调用等等)。gradle的执行其实就是由各种任务组合执行,来对项目进行构建的。

使用gradlew help命令,任何gradle项目都有一个该task,可以执行此命令观察taks执行的流程是否如预期。

可以使用工具查看,还可以通过 gradlew tasks 命令查看可运行任务。

使用gradlew tasks --all 命令查看所有任务。

使用gradlew A B 命令表示执行任务A和B,支持驼峰简写。

我们创建一个简单的Andoid项目在app下的build.gradle中来试着写一个简单的任务
在这里插入图片描述
我们可以点击绿色三角执行该任务,也可以使用命令行执行,命令行执行如下:任选其一,即可在控制台看到输出的结果

D:\TestCode\GeadleLearning>gradlew pH

D:\TestCode\GeadleLearning>gradlew printHello

在这里插入图片描述
关于task的其它特性

task A {
    doLast {
        println "doLast A ..."
    }
}

task C {
    doLast {
        println "doLast C ..."
    }
}

task B {
    doLast {
        println "doLast B ..."
    }
}
// hello 任务依赖于A、B、C三个任务,按照Gradle任务列表中的顺序进行执行
task hello(dependsOn: [A, C, B]) {
    //任务执行的时候首先执行该闭包
    doFirst {
        println "doFirst hello start..."
    }

    //任务执行到最后执行该闭包
    doLast {
        println "doLast hello end..."
    }
}

//指定依赖关系,任务A依赖于任务C,再运行任务A之前先运行任务C
A.dependsOn C

//A必须运行再B运行之后
A.mustRunAfter B

task finalized {
    doLast {
        println "清理一些资源"
    }
}

//通过自定义任务类来实现任务
class MyTask extends DefaultTask {
    @Input
    String filePath

    @OutputFile
    File outFile

    //指定任务所在的分组
    MyTask() {
        group "自定义任务"
        description "我是一个自定义任务"
    }

    @TaskAction
    void runAction1() {
        println "MyTask runAction1"
    }

    @TaskAction
    void runAction2() {
        println "MyTask runAction2"
    }

    void sayHello(String str) {
        println str
    }
}

//创建名为myTask类型为MyTask的任务
tasks.create("myTask", MyTask)

在这里插入图片描述

Geadle执行流程

图片来源于网络

Gradle钩子函数

gradle在各个生命周期阶段都设置了自己的钩子函数,开发者可以利用这些函数进行自定义的构建

初始化阶段:gradle.settingsEvaluated和gradle.projectsLoaded。(在settings.gradle中生效)

配置阶段:project.beforeEvaluate和project.afterEvaluate;gradle.beforeProject、gradle.afterProject及gradle.taskGraph.taskGraph.whenReady。

执行阶段:gradle.taskGraph.beforeTask和gradle.taskGraph.afterTask。

/**
 * Gradle 钩子函数
 * 1、初始化阶段---->settings.gradle文件
 * 2、配置阶段,对于的其实就是build.gradle文件
 */
//gradle 针对所有项目的配置阶段
gradle.beforeProject {
    println "gradle.beforeProject"
}
gradle.afterProject {
    println "gradle.afterProject"
}
gradle.taskGraph.whenReady {
    println "gradle.taskGraph.whenReady"
}
//project只针对当前Module生效
project.beforeEvaluate {
    //在root中无效
    println "app.project.beforeEvaluate"
}
project.afterEvaluate {
    println "app.project.afterEvaluate"
}

除此之外,我们还可以给Geadle对象设置监听

gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
    @Override
    void beforeEvaluate(Project project) {
        //如果是在Module的build.gradle中并不会执行该方法
        println "beforeEvaluate(Project project)"
    }

    @Override
    void afterEvaluate(Project project, ProjectState projectState) {
        println "afterEvaluate(Project project, ProjectState projectState)"
    }
})

gradle.addBuildListener(new BuildListener() {
    @Override
    void settingsEvaluated(Settings settings) {
        println "初始化阶段"
    }

    @Override
    void projectsLoaded(Gradle gradle) {
        println "加载阶段"
    }

    @Override
    void projectsEvaluated(Gradle gradle) {
        println "配置阶段"
    }

    @Override
    void buildFinished(BuildResult buildResult) {
        println "构建结束时调用"
    }
})

Gradle依赖管理

在一个拥有复杂功能的Android项目中,往往少不了许多的第三方SDK与模块化管理,而Gradle在这些复杂的SDK依赖关系、模块间的依赖关系中起着至关重要的作用,下面就来介绍下Geadle如何管理各种各样的依赖关系吧。

工程下的build.gradle

在整个工程下的build.gradle中,版本较低的AndroidStudio在构建项目时会在此脚本中添加一些关于项目构建的一些插件

//低版本AS创建的项目在build.gradle文件中添加插件的依赖
dependencies {
    classpath 'com.android.tools.build:gradle:7.1.2'
    classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
//顶级构建文件,您可以在其中添加所有子项目/模块通用的配置选项(AS版本:Electric Eel | 2022.1.1 Patch 1)
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}

可以看到新版本并没有指定插件的版本,没有显式的添加插件,可能是集成到AS里了,需要查阅官方文档以及Gradle文档,这个关系不大。

仓库的指定

Gradle既然类似于Maven,那么他就有仓库,他在脚本中是这样指定仓库的,在新版本AS中,指定仓库已经放到了settings.gradle脚本中

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "GradleLearning3"
//老版本 对所有工程进行配置
allprojects {
    //为工程添加依赖仓库
    repositories {
        google()//Google的maven中央仓库
        mavenCentral()//maven中央仓库
        jcenter()//过时不维护
        maven {//从某个地址获取
        	url "xxxxxxx"
        }
    }
}
依赖项配置

在 dependencies 代码块内,我们可以选择不同的依赖项配置来声明库的依赖项,每种不同的依赖项都具有不同的特点,详情可以参考Google对依赖项配置的文档
这里截取一部分
在这里插入图片描述

Gradle依赖优化

当我们使用Gradle来管理项目依赖的时候,Gradle再编译的时候会对我们的依赖进行优化,例如我们在app模块的依赖中依赖重复的库,在编译之后查看依赖情况:

dependencies {
    implementation 'androidx.core:core-ktx:1.7.0'
    
    //重复导入一个库的不同版本,是否会发生依赖冲突呢???
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'androidx.appcompat:appcompat:1.4.0'
    implementation 'androidx.appcompat:appcompat:1.4.+'
    
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

我们使用命令:gradlew :app:dependencies --configuration releaseRuntimeClassPath查看编译后的依赖情况,常见三种情况解释如图:

在这里插入图片描述

我们在从输出信息当中寻找到我们重复依赖的androidx.appcompat:appcompat,看Gradle是如何处理的,结果如下图:我们可以看到不管是低版本还是取最新版本都被替换成最新版本,并且这两条依赖都是被忽略的,因为最新版本的该库在前面已经被添加了。

在这里插入图片描述

依赖冲突
依赖冲突的本质就是存在两个同样的类,这两个类具有相同的包名和类名,这在java中是不被允许的,因此就会产生依赖冲突。
例如我们引入了一个依赖包,他的结构如下,如果在另一个依赖中包含如下红框中的一些类的话,就会产生依赖冲突,那么我们如何解决呢?
在这里插入图片描述

假设我们需要排除红框中的依赖包,我们可以选择一下方式来解决:

    implementation('androidx.room:room-runtime:2.5.0') {
        exclude group: 'androidx.room', module: 'room-common'
    }

再次使用gradlew :app:dependencies --configuration releaseRuntimeClassPath进行编译:已经没有之前的子Module依赖了,因此可以通过上述方式解决依赖冲突。

在这里插入图片描述
还可以将整个依赖下面的某个Group干掉,可以发现以androidx.sqlite开头的Group全部消失了

    implementation('androidx.room:room-runtime:2.5.0') {
//        exclude group: 'androidx.room', module: 'room-common'
        exclude group:'androidx.sqlite'
    }

在这里插入图片描述
使用全部排除

//在Build.gradle添加如下代码即可去掉所有依赖中模块为annotation的依赖包
configurations {
    configuration {
       all*.exclude module:"annotation"
    }
}

强制指定某个依赖的版本

//(build.gradle的根节点)
configurations.all{
    resolutionStrategy {
        //强制指定版本
        force 'androidx.appcompat:appcompat:1.1.0'
    }
}

在这里插入图片描述

依赖传递

依赖传递就是用来控制某个模块导入的包是否可以被其它模块直接使用,主要涉及implementation 与 api
最简单的解释如下:

ABCD四个模块
A implementation  BB implementation CA不能使用C
A implementation  BB api CA可以使用C
A implementation  BB implementation  C ,C api DB可以使用DA不能使用D
A implementation  BB api  C ,C api DA可以使用D
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了满足广大Android开发爱好者与从业者的学习需求,我们精心整理并上传了一份全面而实用的Android项目资源包。这份资源包内容丰富,涵盖了从基础知识到实战应用的全方位内容,旨在为开发者们提供一个便捷、高效的学习平台。 一、文件手册 资源包中的文件手册部分,详细记录了Android开发的核心知识点和常用技术。无论是初学者还是有一定经验的开发者,都能从中找到所需的学习资料。手册采用了简洁明了的排版方式,使得查阅更加方便快捷。同时,手册内容深入浅出,既适合新手入门,也能为老手提供有价值的参考。 二、项目实战与练习 为了让学习者能够将理论知识与实践相结合,我们特别准备了项目实战与练习部分。这部分内容包含了多个精心设计的Android项目案例,从需求分析、设计思路到实现过程,都有详细的讲解和代码示例。学习者可以通过实际操作,深入了解Android开发的整个流程,提升自己的实战能力。 此外,我们还提供了一系列练习题,旨在巩固所学知识,检验学习成果。这些练习题既有基础题,也有难度较高的挑战题,适合不同层次的学习者进行练习。 三、Android开发工具集 在Android开发过程中,选择合适的工具能够大大提高开发效率。因此,我们整理了常用的Android开发工具集,包括开发工具、测试工具、性能优化工具等。这些工具都是经过我们精心筛选和测试的,能够帮助开发者们更加高效地进行Android开发工作。 总的来说,这份Android项目资源包是一份不可多得的学习资料,无论你是初学者还是有一定经验的开发者,都能从中受益匪浅。我们希望通过这份资源包,为广大Android开发爱好者与从业者提供一个更加便捷、高效的学习平台,共同推动Android开发领域的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值