前言

这篇文章定义为入门篇,将结合自己刚开始学习Android时的疑惑与现在对Gradle的认识,进一步整理Gradle在Android中的整体结构。

思考

当我使用Android Studio时,一直有几个疑问围绕着我:

  1. Android Studio是怎样将Java与Kotlin代码的编译成APK文件?

  2. Gradle是怎样将Java与Kotlin代码编译成APK文件?

后来知道Android Studio自身是不能够编译成APK的,它是集成了Gradle。通过研究Gradle,发现Gradle也只是一个构建工具,真正编译成APK的功能是由Android app plugins提供的。Gradle只是自动化构建工具,提供构建时的各种生命周期,例如:building、testing、publishing等。所以Gradle不仅支持Android还支持C/C++、Scale等。

而这个plugin其实就是在project中的build.gradle中声明的classpath

 1buildscript { 2    repositories { 3        // Gradle 4.1 and higher include support for Google's Maven repo using 4        // the google() method. And you need to include this repo to download 5        // Android Gradle plugin 3.0.0 or higher. 6        google() 7        ... 8    } 9    dependencies {10        classpath 'com.android.tools.build:gradle:3.4.0'11    }12}

所有每次对Android构建进行了优化,我们都要来更新这个版本。

Scripts

有了上面的基础,当我们新建一个Android项目时,你将会看到如下与Gradle相关的文件:

你会看到文件名几乎都有gradle字段,下面我会一一介绍它们的作用

Gradle Wrapper

首先是gradle-wrapper.properties文件,打开它你将会看到如下类似信息

1#Sat Jan 19 08:25:46 CST 20192distributionBase=GRADLE_USER_HOME3distributionPath=wrapper/dists4zipStoreBase=GRADLE_USER_HOME5zipStorePath=wrapper/dists6distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

这个是gradle版本的配置项,申明你当前项目中使用的gradle版本。当我们构建项目的时候,它会根据版本自动下载。并且保存到你的电脑本地中。如果你使用的是Mac,你可以使用如下命令查看你的所有已经下载的gradle版本。

1ls ~/.gradle/wrapper/dists/

所以如果你不满意当前版本,也可以通过查看version of Gradle(https://gradle.org/releases/)修改到相应的版本

settings.gradle

这个文件是项目与其子项目或者module间的配置。里面通过include函数来告诉该项目所包换的子项目或者依赖的module。例如刚新建项目时只有一个app子项目。

1include ':app'

所以settings.gradle是位于project的最外层,即与app同级。

build.gradle

现在我们已经知道一个project可以包含一个或者多个sub-projects,而Android一般会将sub-projects当做module,所以你会在这看到两个build.gradle。根据后面的hint提示,发现它们分别来自与project与module。

首先我们来看project中的build.gradle,即位于根目录下的文件

 1buildscript { //1 2 3    ext.objectboxVersion = '2.3.0' //4 4 5    repositories { //2 6        google() 7        jcenter() 8    } 9    dependencies { //310        classpath 'com.android.tools.build:gradle:3.3.2'11        classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"        12    }1314}1516allprojects { //517    repositories {18        google()19        jcenter()20    }21}2223task clean(type: Delete) { //624    delete rootProject.buildDir25}
  1. buildscript闭包是申明编译该项目所需的相关配置

  2. 告知gradle这些配置将从google()与jcenter()中获取

  3. 申明相关的plugin,例如Android Plugin for Gradle。

  4. 在gradle中有一个extra property属性,允许我们通过它来申明一些变量,例如plugin的版本号。有一个特性就是这些变量在gradle中都是全局的。所以对于多个module时,我们可以通过它来统一相关的版本号。最后在3中通过${name}来引用

  5. 因为可能有多个sub-project,对于一些相同的配置,可以通过allprojects来进行统一管理。

  6. 申明一个task,用来执行相关任务,这里是clean操作,目的是删除build文件夹中的数据

下面是module中的build.gradle

 1apply plugin: 'com.android.application' 2apply plugin: 'io.objectbox' //1 3 4android { //2 5    compileSdkVersion 28 6    defaultConfig { 7        minSdkVersion 21 8        targetSdkVersion 27 9        versionCode 10000510        versionName "1.0.5"11        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"12    }13    buildTypes {14       release {15            minifyEnabled false16            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'17        }18    }19}2021dependencies { //322    implementation fileTree(include: ['*.jar'], dir: 'libs')23    implementation 'com.android.support:appcompat-v7:28.0.0'24    implementation 'com.android.support:support-v4:28.0.0'25}
  1. 通过调用apply函数,引入我们需要依赖的plugin,这个就是我们在根build.gradle中申明的classpath

  2. android闭包是gradle最重要的配置申明,例如默认的配置信息defaultConfig,包含minSdkVersion最小支持的android版本,versionCode与versionName等。这些配置都与编译息息相关,最好你应该熟悉它们。你实在记不住的话,我这里也有秘籍,AppExtension(https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.AppExtension.html)这里面包含所有的配置项与所代表的意义。

  3. 这里的dependencies用来申明项目所依赖的第三方库,而这些库的获取来源无需再次申明,因为我们已经在之前的根目录的build.gradle中的allprojects闭包中进行了申明。再者之前的ext全局变量也可以在这里使用。

gradle.properties

这个文件一般都是本地文件,主要用来对gradle构建的一些个人配置项。例如gradle运行是否并行,gradle的jvmargs大小、是否开启daemon等等。它会在gradle运行时注入到相应的build.gradle中。

local.properties

这个文件也是本地文件,只不过它用来配置gradle之外的配置信息,例如ndk与sdk目录,或者一些敏感的信息,例如插件开发打包上传到远程仓库这时可能需要账号、密码、api_key等,防止打包时暴露。

Gradle Tasks

gradle tasks是用来执行特定的gradle任务的。我们可以直接点击Android Studio右边的Gradle按钮,你会发现在Tasks下会列出该项目的所用可执行的gradle任务。

image

或者你也可以在命令行中执行如下命令,查看app下的所有tasks

1./gradlew app:tasks

我们顺便点击一个,例如assembleDebug,我们将会在Run日志系统中看到如下执行结果

根据输出的日志,也标明它是执行了task: assembleDebug

当然我们也可以在命令行执行指定的task,例如要达到上面相同的效果,我们可以输入如下命令

1./gradlew assembleDebug --console plain
  1. ./gradlew 代表的是使用Gradle Wrapper中的gradle,就是该项目本身的gradle版本,避免直接使用gradle命令

  2. assembleDebug是task的名称

  3. --console plain输出完整的日志

既然说到这里,再说一个初级者容易做的无意义的操作。有时会碰到一些问题而去点击Clean Project,再点击Rebuild Project。其实Clean Project是不必要的。我们可以直接先点击Rebuild Project,查看日志

结果是它分别执行了task: clean,assembleDebug。所以Rebuild Project就已经包含了Clean Project,我们无需多此一举执行Clean Project。

最后

嗯,就这些。最后,希望这篇文章,能够让大家对gradle在项目中的结构与所处的地位有一个更清晰的理解

更多相关文章

  1. 老项目代码从Eclipse迁移到AndroidStudio
  2. Android(安卓)Studio配置文件修改
  3. Android应用程序结构--比较偏的考试题目
  4. Android(安卓)Studio集成百度云推送
  5. Android.bp入门指南之Android.mk转换成Android.bp
  6. 设置Activity大小不再全屏原理
  7. Android(安卓)程序适应多种多分辨率
  8. Android(安卓)Studio使用lambda
  9. Your project contains error(s)... 如何解决?

随机推荐

  1. Android中Activity, View,Window,DecorVi
  2. Android(安卓)Socket与HTTPS校验
  3. 超新鲜的字节客户端Android面经,附面试题
  4. 2015年11月广师android群内容分享
  5. Android手机分辨率问题
  6. 在android上向nodejs中添加第三方node模
  7. daliu_IT学习Android笔记第一篇--Android
  8. android博客导航总结,以及个人常用android
  9. 改变Android按钮背景颜色的高效方法
  10. Android连接mysql demo_Android实现登陆