SimpleNews 项目的重构之旅(4) -Gradle for Android 基础知识汇总

字数 882阅读 165

Gradle

使用 Android Studio 都知道 Gradle,在 SimpleNews 项目中,前期的时候并不是很了解 Gradle 语法等,只是使用 Android Studio 默认的配置来构建,后续也只是关注在功能方向,没有过多的了解 Gradle 使用,趁此重构机会就好好认识 Gradle。

我们来看下维基百科简单了解下概念:

image.png

可以看到 Gradle 的优势,我之前也使用过 Ant 打包,相对于Ant xml 的编写,Gradle 使用简单易理解。

如果我们不是负责项目的打包或者渠道发布等工作,这里我们了解下 Gradle 常用的基本配置就可以了,也能满足我们的日常需求。

要是想精通的话,建议看看 Gradle for Android 这本书,并动手操练,这里推荐 Android Gradle 插件中文指南

SimpleNews.io 项目中使用的 gradle build 版本是 gradle:2.3.2

接下来挨个文件看,项目中的基本上都添加了注释,很容易理解,后续再清理。

基本的 settings.gradle 文件

include ':app', ':library'
//包含多个模块即多个module

Android 项目级别的 build.gradle 文件

// Top-level build file where you can add configuration options common to all sub-projects/modules.

//顶级的构建文件,需要到子项目中添加依赖
//应用配置文件,完事之后可以在全局引用
apply from: "config.gradle"
// 中央远程仓库,兼容maven中心仓库
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.2'//项目使用 gradle:2.3.2 版本 build

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        //不要再这里添加依赖,在各自的module build.gradle中添加依赖
    }
}
//为所有的工程的repositories配置为jcenters,JCenter类似maven库,不需要任何额外的配置
allprojects {
    repositories {
        jcenter()
    }
}

//buildscript 方法是定义了全局的相关属性,repositories定义了jcenter作为仓库。一个仓库代表着你的依赖包的来源,
// 例如maven仓库。dependencies用来定义构建过程。这意味着你不应该在该方法体内定义子模块的依赖包,你仅仅需要定义默认的Android插件就可以了,
// 因为该插件可以让你执行相关Android的tasks。

Android 项目 App 级别 build.gradle 文件

apply plugin: 'com.android.application'
//该 plugin 为一个 com.android.application 程序,也就是应用程序,如果你的 plugin 是一个库,那么自然也就是apply plugin: 'com.android.library'

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion //编译的 SDK API 版本
    buildToolsVersion rootProject.ext.android.buildToolsVersion //构建工具版本

    //默认配置&核心属性,该属性会重写在AndroidManifest.xml中的对应属性
    defaultConfig {
        applicationId rootProject.ext.android.applicationId//配置包名的
        minSdkVersion rootProject.ext.android.minSdkVersion //支持最小的 SDK 版本
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode//版本号
        versionName rootProject.ext.android.versionName//版本名称
    }
    //构建类型,常用的有release和debug两种
    buildTypes {
        release {
            minifyEnabled true //是否启动混淆
            shrinkResources true //是否移除无用资源文件,shrinkResources依赖于minifyEnabled
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

repositories {
    jcenter()
    maven { url "https://jitpack.io" }
}

//依赖管理,可以添加远程依赖 和 本地依赖libs等
dependencies {
    //将libs文件夹中所有的jar文件视为依赖包。
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'

    //添加依赖包
    compile project(':library')

    //依赖远程仓库
    compile rootProject.ext.dependencies.design
    compile rootProject.ext.dependencies.cardview
    compile rootProject.ext.dependencies.circleimageview
    compile rootProject.ext.dependencies.sufficientlysecure
}

Android 项目 Library 级别 build.gradle 文件

这里的配置基本上和 App 中的配置一样,之前介绍过,使用 config.gradle 来统一全局变量,就不多介绍了,不知道的可以查看第一篇

apply plugin: 'com.android.library'

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion


    defaultConfig {
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile rootProject.ext.dependencies.appcompat
    compile rootProject.ext.dependencies.gson
    compile rootProject.ext.dependencies.glide
    compile rootProject.ext.dependencies.okhttp
    compile rootProject.ext.dependencies.rxandroid
    compile rootProject.ext.dependencies.eventbus
}

so、jar、aar文件

jar:只包含了 class 文件与清单文件,不包含资源文件;

aar:包含所有资源,class以及res资源文件。

aar使用

当你构建你的library项目,aar文件将会在 build/output/aar/下生成。

image.png

可以创建一个 aars 文件夹来存放 aar 文件,并将本目录下所有的 aar 文件作为依赖包,例如:

repositories {
    flatDir {
        dirs 'aars' 
    }
}

so:用c或者c++写的 library 会被叫做 so 包,Android 插件默认情况下支持native包,你需要把.so文件放在对应的文件夹中:

app
   ├── AndroidManifest.xml
   └── jniLibs
       ├── armeabi
       │   └── nativelib.so
       ├── armeabi-v7a
       │   └── nativelib.so
       ├── mips
       │   └── nativelib.so
       └── x86
           └── nativelib.so

使用系统的 load 方法,就能加载,有两种方式,这里就不多介绍了,等用到了在说。

其他文件

1、gradle-wrapper.properties

#Fri May 26 10:09:38 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
#声明gradle的目录与下载路径以及当前项目使用的gradle版本,一般不会更改的

2、proguard-rules.pro

每一个 module 都会有自己的 proguard-rules.pro 文件,用来编写混淆规则,有一些是不能被混淆的
例如:一些js注入类是不能被混淆的,否则调用找不到方法。

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

3、gradle.properties

说到这个文件就要说到之前的 config.gradle 来统一全局变量,config.gradle 只是一种方式,我们还可以在 gradle.properties 中
定义常量。

例如(不是本项目中的使用方式,摘自网络):

# 应用版本名称
VERSION_NAME=1.0.0
# 应用版本号
VERSION_CODE=100
# 支持库版本
SUPPORT_LIBRARY=24.2.1
# MIN_SDK_VERSION
ANDROID_BUILD_MIN_SDK_VERSION=14
# TARGET_SDK_VERSION
ANDROID_BUILD_TARGET_SDK_VERSION=24
# BUILD_SDK_VERSION
ANDROID_BUILD_SDK_VERSION=24
# BUILD_TOOLS_VERSION
ANDROID_BUILD_TOOLS_VERSION=24.0.3

android {
    compileSdkVersion project.ANDROID_BUILD_SDK_VERSION as int
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
 
    defaultConfig {
        applicationId project.APPLICATION_ID
        versionCode project.VERSION_CODE as int
        versionName project.VERSION_NAME
        minSdkVersion project.ANDROID_BUILD_MIN_SDK_VERSION as int
        targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int
    }
}

4、local.properties

这个比较简单,就是配置项目 NDK、SDK 路径

总结

本文只是简单的介绍了项目中使用的 Gradle 脚本含义和简单用法,只是 Gradle 使用当中的冰山一角,之后会深入打包功能,让项目越来越完善。

参考

Gradle for Android 第一篇( 从 Gradle 和 AS 开始 )


SimpleNews 项目的重构之旅其他文章

SimpleNews 项目的重构之旅(1) -项目架构定位 & Gradle 全局配置
SimpleNews 项目的重构之旅(2) - 整理项目 .gitignore 文件
SimpleNews 项目的重构之旅(3) -EventBus 接入
SimpleNews 项目的重构之旅(4) -Gradle for Android 基础知识汇总
SimpleNews 项目的重构之旅(5) - Android Gradle 打包&混淆应用
SimpleNews 项目的重构之旅(6) - 命名规范 & Android Toolbar
SimpleNews 项目的重构之旅(7) - 改头换面&深度清理

推荐阅读更多精彩内容