Android插件

Android插件

前面我们说到Gradle插件其实并没有提供真正的构建功能, 我们编译构建的Task很多都是由插件来提供的,如果对这点还不是很了解可以先看下Gradle脚本学习

Java插件

在某种意义上,android插件算是在java插件的基础上扩展而来的,而java插件也是Gradle官方支持的插件之一,为了让大家能够更好的理解Android插件中各个Task的执行和依赖关系,我们现对Java插件做一个介绍,英语好的同学可以直接去阅读Gradle官方The Java Plugin
Java插件的使用很简单,毕竟是官方支持的

apply plugin: 'java'

这样就可以了,对于java插件我们主要理解一张Tasks图表


Android插件_第1张图片
javaPluginTasks.png

这里包含了java插件中的绝大部分Tasks,图标中的Task描述如下

名称 依赖 TaskType 描述
compileJava 所有处理编译过程的任务 JavaCompile 使用javac编译java源码
processResources - Copy 把资源文件复制到相应目录
classes complileJava和processResources Task 生成.class文件和资源文件目录
compileTestJava compile,加上编译测试文件的所有Task JavaCompile 使用javac编译java测试代码
processTestResources - Copy 把测试资源文件复制到相应目录
testClasses compileTestJava和processTestResources Task 申城测试的.class文件和资源文件目录
jar compile Jar 生产jar文件
javadoc compile Javadoc 使用javadoc生产Api文档
test compile Test 使用JUnit或TestNG运行单元测试
uploadArchives 生成所有archives需要的artifacts文件的Task,包括jar Upload 使用archives配置上传artifacts包括jar文件
assemble 项目中的所有archive任务,包括jar Task 生成项目所有的archive文件
check 项目中的所有验证任务,包括test Task 执行所有项目中的验证任务
build assemble和check Task 执行完整的项目构建
clean - Delete 删除项目构建过程生成的文件目录
clean TaskName - Delete 删除指定任务创建的文件。 cleanJar将删除由jar任务创建的JAR文件,cleanTest将删除测试任务创建的文件

我们平时使用当然不可能一步步去编译,往往只会使用几个相对简单的命令,比如check、assemable之类的,但是如果我们对整个build的流程不了解,我们就很难在构建过程中对某一个具体的行为进行优化,这里先讲解java插件,是因为java的构建过程相对简明,Android工程的构建过程就相对复杂很多,但是本质上都差不多,建议大家还是可以先学习下

Android插件

Android插件是由google提供,用于配置、编译、打包android工程,它提供了一些新的DSL和task供我们配置,执行android工程的编译打包过程,关于android插件的使用个人建议可以看下Google提供的GradlePluginUserGuide和AndroidPluginDSL,这里我就算是抛砖引玉了

基本配置

android下最基本的配置很简单,完成最基本的配置之后Gradle就能够对我们的project进行构建,同时还有一些的零碎的配置,我也一并并在这里进行说明最最简单的,我们只需要配置compileSdkVersion和buildtoolsVersion

apply plugin: 'com.android.application' 
android { 
    compileSdkVersion 25 
    buildToolsVersion "25.0.0" 
}

这样就可以完成构建,当然我们还需要配置一些Apk的基本信息,这些信息主要通过defaultConfig{}来进行配置,主要的信息如下

  • minSdkVersion
  • targetSdkVersion
  • versionCode
  • versionName
  • applicationId
  • testApplicationId (used by the test APK)
  • testInstrumentationRunner

前四条都是一些基本的版本配置信息其中值得一提的是applicationId 这条属性,形式上和packageName是一致的,当我们使用AndroidStudio创建工程是,applicationId默认是和packageName一样,但是这两者是有本质区别的,packageName是可以改变的,但是applicationId一旦应用发布就不能修改了,applicationId是APK的标识,同时不同渠道版本的applicationId最好也进行不同的配置,这个稍后进行详细说明
关于test的配置信息,也会在后面的章节详细说明

sourceSets

资源目录Android插件的默认资源目录如下

src/ 
├──main/ 
│     ├── java/ 
│     ├── resources/ 
│     ├── res/
│     ├── assets/ 
│     ├── aidl/ 
│     ├── rs/ 
│     ├── jni/ 
│     ├── jniLibs/ 
│     └── AndroidManifest.xml 
├── test/ 
└── androidTest/

如果需要更改目录需要手动修改,例如对于一般的eclipse工程我们可以使用下面的配置

android { 
    sourceSets { 
        main { 
            manifest.srcFile 'AndroidManifest.xml' 
            java.srcDirs = ['src'] 
            resources.srcDirs = ['src'] 
            aidl.srcDirs = ['src'] 
            renderscript.srcDirs = ['src'] 
            res.srcDirs = ['res'] 
            assets.srcDirs = ['assets'] 
        }  
        androidTest.setRoot('tests') 
    } 
}

这样就无需手动更改文件目录,也可以直接编译

Dependencies Configration

前面我们说到dependencies本质上就是一个配置信息,Android插件提供的dependencies主要有:

  • compile: main application
  • androidTestCompile: test application
  • debugCompile: debug Build Type
  • releaseCompile: release Build Type
  • testComplie:上面四种是google官方文档上写的,事实上testComplie这种纯java的test配置也是支持的

根据版本变种,android插件也会生成不同的dependencies,就像android自带的两种buildtype就生成了上面两种dependencies

Android Tasks

前面在gradle我们说到,在gradle中实际的执行是通过Task来进行的,Android插件能够对我们的Project进行构建,必然也提供了相应的Task才能完成构建,我们主要要用到的主要有下面几个

  • assemble生成输出,会执行构建过程
  • check运行所有检查任务
  • connectedCheck运行检查连接的设备或模拟器,所有连接的设备将并行运行。
  • deviceCheck使用API​​运行检查以连接到远程设备,这在CI服务器上使用。
  • build这个任务会运行assemble和check。
  • clean此任务清除项目的输出。

感觉和java插件大体相似,只是多了两个类似设备检查之类的task,但是事实上,android工程的构建过程还是比较复杂的,所以android插件并没有给出构建过程中具体的tasks,以及task间的依赖关系,更没有java插件中提供的task依赖表。

那么我们要怎么才能弄清android构建的具体过程呢,这里我为大家介绍一个插件Inspector,具体使用方法参考GitHub:https://github.com/jakeouellette/inspector,我就不多做介绍,这个插件可以生成我们所运行的task的依赖关系图,方便大家理解学习。

注意:Inspector不支持windows!不支持windows!不支持windows!

版本变种的配置

BuildType配置

版本变种中有两个内容,BuildType和ProductFlavor,首先是关于BuildType,Android插件默认提供debug和release两种BuildType,当然我们也可以自己添加新的BuildType,Android下对于每一种BuildType都可以有各自的配置信息,同时可以根据配置信息生成独特apk,首先对于不同的BuildType,我们会有不同的dependencies配置compile类型,就像上面 dubugCompile一样,类似下面的代码

android { 
    buildTypes { 
        jnidebug { 
        } 
    } 
}

就会生成一个jnidebugCompile,前面我们说过aseemble这个task可以生产所有的输出,这里我们有三个BuildType,即assemble会生成3个不同Apk,如果我们只需要生成debug的Apk,这里和compile一样,Android插件也会生成一个assembleDubug的task,运行assembleDubug则不会生成其他版本的Apk
BuildType的配置就在buildTypes{}的闭包中

android {
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
        jnidebug {
            initWith(buildTypes.debug)           
            applicationIdSuffix ".jnidebug"
            jniDebuggable true
        }
    }
}

其实我觉得这些东西反而没有什么好讲的,配置基本上就是一个表,列出所有可配置的东西,这里我姑且还是把一些我感觉可用的配置和方法都列出来,大家也可以参考官方文档

名称|类型|说明
---|--|--|--
applicationIdSuffix|String|为 applicationId添加后缀,applicationId是app唯一标识,每次调用都是在最开始的applicationId上添加
debuggable|Boolean|调试开关
consumerProguardFiles|List|生成的aar文件中的混淆规则,只针对Library工程
jniDebuggable|Boolean|jniDebug开关
minifyEnabled|Boolean|混淆开关
signingConfig|SigningConfig|签名配置
proguardFiles|List|生成apk时使用的混淆配置文件
shrinkResources|Boolean|移除没有用到的资源文件,默认为false
embedMicroApp|Boolean|Android Wear app是否需要嵌入此build type
manifestPlaceholders|Map|配置manifest属性,合并时使用这里的属性
multiDexEnabled|Boolean|Multi-Dex开关
multiDexKeepFile|File|main dex的配置文件,text文件,每行指定一个class文件,格式为com/example/MyClass.class
multiDexKeepProguard|File|main dex的混淆规则,会和构建系统的混淆规则合并
zipAlignEnabled|Boolean|压缩对齐开关
[buildConfigField](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html#com.android.build.gradle.internal.dsl.BuildType:buildConfigField(java.lang.String, java.lang.String, java.lang.String))(String, String, String)|Method|为生成的BuildConfig添加键值对
initWith(BuildType)|Method|复制所有属性

SigningConfig

Android 要求所有 APK 必须先使用证书进行数字签署,然后才能安装。Android插件已经帮我们配置了两种BuildType:debug和release,其中debug默认使用Android自动生成的dubug Signing,而release默认是没有配置Signing的,我们可以直接在代码中进行Signing的配置

android {
    signingConfigs {
        release{
            storeFile file("other.keystore")
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
    }
    buildTypes {
        release{
            signingConfig signingConfigs.release
        }
    }    
}

这里我们我们通过signingConfigs{}配置了一个release的signing,然后在配置buildTypes 的时候把它配置到,release的配置闭包中, 这里可以简单的把signingConfigs理解为一个配置文件,在上面我们直接keystore的pwd写在了代码中, 一般是不建议这么,我们通常使用一个专门的配置文件来存储signingConfigs,需要的时候从文件中读取,或者从控制台输入。

BuildConfig

在编译时期,Android插件会生成一个BuildConfig的类,包含部分Gralde配置中的常量默认BuildConfig有下列信息:

  • boolean DEBUG 是否可以dubug
  • int VERSION_CODE
  • String VERSION_NAME
  • String APPLICATION_ID
  • String BUILD_TYPE – name of the build type, e.g. "release"
  • String FLAVOR – name of the flavor, e.g. "paidapp"

同时我们也可以通过buildConfigField(String, String, String)把我们需要的配置信息加入到BuildConfig中

ProductFlavor配置

ProductFlavor的配置和BuildType基本类似,同时也会生成相应的Task和Compile,主要区别就是BuildType的分类是针对开发者的,如debug、release,而ProductFlavor的分类是针对用户的,如free、pay,所以可配置的内容是不同的,ProductFlavor的配置信息主要如下:

名称|类型|说明
---|--|--|--
applicationId|String|-
applicationIdSuffix|String|为 applicationId添加后缀,applicationId是app唯一标识,每次调用都是在最开始的applicationId上添加
consumerProguardFiles|List|生成的aar文件中的混淆规则,只针对Library工程
dimension|String|此flavor的dimensioin类型
externalNativeBuild|ExternalNativeBuildOptions|封装了native相关构建的信息
jackOptions|JackOptions|jack配置
signingConfig|SigningConfig|签名配置
proguardFiles|List|生成apk时使用的混淆配置文件
manifestPlaceholders|Map|配置manifest属性,合并时使用这里的属性
multiDexEnabled|Boolean|Multi-Dex开关
multiDexKeepFile|File|main dex的配置文件,text文件,每行指定一个class文件,格式为com/example/MyClass.class
multiDexKeepProguard|File|main dex的混淆规则,会和构建系统的混淆规则合并
[buildConfigField](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html#com.android.build.gradle.internal.dsl.BuildType:buildConfigField(java.lang.String, java.lang.String, java.lang.String))(String, String, String)|Method|为生成的BuildConfig添加键值对
maxSdkVersion(int or String)|Method|设置flavor最高sdk版本
minSdkVersion(int or String)|Method|设置flavor最低sdk版本

Build Variant

我们知道一种BuildType会生产一种Apk,ProductFlavor也是一样的,那个一个工程可以产出的不同种类的apk将是这两者的合并,比如一个有两个Flavor的工程,加上默认的BuildType,则会生成下面几个版本:

  • Flavor1 - debug
  • Flavor1 - release
  • Flavor2 - debug
  • Flavor2 - release

Build Type + Product Flavor = Build Variant

Sourcesets and Dependencies

不同的BuildVariant可以有不同的资源和依赖,他们同时共享主目录下的资源,举个例子flavor1Debug这样一个Variant,它的资源可能来自如下目录

  • android.sourceSets.main
    位于 src/main/
  • android.sourceSets.flavor1
    位于 src/flavor1/
  • android.sourceSets.debug
    位于 src/debug/
  • android.sourceSets.flavor1Debug
    位于 src/flavor1Debug/

如果出现同名的文件那么他们的优先级顺序是flavor1Debug>debug>flavor1>main,一层会覆盖一层。对于Dependencies,这个规则也是一样的。

小结

Android插件的内容并不算多,但是想要用好Gradle,我们除了要了解这些东西之外,还需要了解Gradle和Groovy提供的API以及一些其他的插件才能更好的使用它。

你可能感兴趣的:(Android插件)