[deprecated]gradle the android

Post on 21-Jan-2018

395 Views

Category:

Mobile

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Gradle the Android 入門篇

Cloud

Overview

Gradle基础姿势!

一丁点儿Groovy语法!

Gradle编译Android项⺫⽬目!

Gradle插件开发

Why Gradle?

gradle ≥ ant + maven + makefile!

gradle + Android Studio ≥ Eclipse + ADT + ant + maven + makefile!

Google选择了gradle

Environment Setup

安装gradle > sudo apt-get install gvm> gvm install gradle !

使用gradle-wrapper ${sdk}/tools/templates/gradle/wrapper即拷即用!

额外的groovy> gvm install groovy > groovyConsole

Terminology

Eclipse Gradle Android Studio

workspace settings.gradle project

project build.gradle module

library project module dependency module library

settings.gradle & build.gradle

settings.gradle: 声明工程中所有Module, settings是gradle找到整个工程的入口!

build.gradle: 每一个build.gradle是所在目录Module的入口 当前Module的DSL入口为 project!

settings.gradle同级目录下的build.gradle也是一个模块的入口, 此模块叫做rootProject 所有子模块都可以通过 rootProject 找到此模块

Diff from Ant

Feature Gradle Ant

Maven √ ×

AAR Dependencies √ ×

Variants for multiple-flavors √ ×

NDK support乄#

(Coming soon in AS)√

Basic Sample for Androidbuildscript { repositories { mavenCentral() } ! dependencies { classpath 'com.android.tools.build:gradle:0.11.1' } } !apply plugin: 'com.android.application' !android { compileSdkVersion 19 buildToolsVersion "19.1.0" }

build.gradle { !

repositories { // 定义插件仓库 mavenCentral() mavenLocal() maven { url uri(‘path/to/your/repo’) } }!

dependencies { classpath ‘group:name:version’ classpath group:’yourDependencyGroup’, name:’yourDependencyName’ version: ‘1.1’ classpath ‘com.meizu:MeizuConfigerPlugin:0.13.1’ }!

}

apply plugin: ‘some.plugin’!

apply plugin: ‘eclipse’!

apply plugin: ‘java’!

apply plugin: ‘com.android .application’!

apply from: ‘path/to/your/shared.gradle’

android { /*!

android DSL 的入口!

用于自定义所有android编译相关!

依赖local.properties中定义的SDK路径如sdk.dir=/Users/me/android/sdk

或者ANDROID_HOME环境变量!

*/}

Basic Groovy Grammars

def name = 'Green' def name = "Green" def quote = """First line |Second line \ |, still in second line. """.stripMargin()!

def fullName = "Jim ${name}" // Jim Green !

def CLOUD_HOME = '/Users/me/flyme/meizu/Cloud' def snsPath = "$CLOUD_HOME/MzSnsSyncService"

def greeting = { name-> println "Hello $name" } void greeting(String name){…} greeting "Jack" // 输出Hello Jack!

def greeting = { println "Hello $it" }!

def handleGreeting = { master, greet, guest-> print "$master says: " greet guest } handGreeting 'Jim', greeting, 'Jack'!

Jim says: Hello Jack

doFirst { // do something } doFirst(Closure cl) { closureList.add(cl) }!

compile.doLast { // do something } <-> compile <<< { // do something }<<< 相当于 add last

aStringList <<< 'Foo'aStringList <<< ['Foo', 'Bar']

class Car { String wheel, door, seat void setWheel(String w) {wheel = w} void getDoor() {door} } def car = new Car() car.wheel = "left wheel" <-> car.setWheel("left wheel") println car.door <-> println car.getDoor()

Operator Mehod

a + b a.plus b

a << b a.leftShift b

a++ a.next()

a[b] a.getAt(b)

a[b] = c a.putAt(b, c)

+a a.positive()

a == b <-> a.equals(b)or a.compareTo(b)

Project Structure

src/libs/ |- armeabi/*.sores/[代码libs之外全是res]

gen/bin/ AndroidManifest.xml

app/ |- build.gradle |- build/ |- libs/ |- src/ |- main/ : |- res/[drawable*|layout*|values*|menu] : |- java/ : |- res/ : |- AndroidManifest.xml : |- [aidl|assets|jni|rs etc.] |- androidTest/ |- [flavors|buildTypes folders] build/ [gradle/ | gradlew | gradlew.bat][build.gradle | settings.gradle]

Configure the Structure

android.sourceSets.main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] sets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] }

tests工程呢?android.sourceSets.androidTest.setRoot('tests')!

等价于android { sourceSets { androidTest.setRoot('tests') androidTest { setRoot 'tests' root = 'tests' } } }!

DSL…

settings.gradle

对于多个module的工程include ':Module1' project(':Module1').projectDir = new File(settingsDir, '../custom/path/module')

settings.gradle中所有include的模块都是子模块, 根模块默认为settings.gradle同级目录build.gradle,

此模块DSL入口叫做rootProject

settings.gradle + build.gradle(rootProject) |- module1/build.gradle(project) |- module2/build.gradle(project) |- custom/path/module3/build.gradle |- ../relative/path/module4/build.gradle |- $workspace/module5/build.gradle!

build.gradle + [settings.gradle] 单独只有⼀一个rootProject可以忽略settings

Default build.gradle

buildscript {//引用仓库, 配置编译classpath }!

android{ compileSdkVersion 19 buildToolsVersion '19.1.0' defaultConfig { versionCode 12 versionName "1.0" minSdkVersion 19 targetSdkVersion 20 applicationId "com.meizu.flyme.cloud" } }!

dependencies { // 定义模块依赖项目 }

Basic Tasks

basic android tasks decription

assemble将一系列编译任务产生的输出#

(outputs)打包成APK

check 检查项⺫⽬目, 主要依赖任务是lint

build assemble+check

clean 清除gradle任务产生的outputs

gradle tasks

Build tasks: assemble*, build, clean!

Verification tasks: *check, lint, test…!

Install tasks: install*, uninstall*!

Help tasks: tasks, projects, help, …!

Build Setup tasks: init, wrapper!

Other tasks: compile**!

Android tasks: androidDependencies, signingReport

Task assemble

assemble* (assembleDebug | assembleRelease) -> preBuild -> compile*Ndk -> prepare*Library -> check*Manifest -> prepare*Dependencies -> compile*Aidl -> compile*Renderscript -> generate*BuildConfig -> generate*Assets-> merge*Assets -> generate*ResValues-> generate*Resources -> merge*Resources-> process*Manifest -> process*Resources -> generate*Sources -> compile*Java -> preDex* -> dex* -> process*JavaRes-> validate*Signing -> package* -> zipalign* -> assemble* done

Tasks outputs

generated intermediates tmp outputs

generated* pre* compile*Java package*

compile* zipalign

check* lint results

merge*

*dex

process*

Gralde Tasks tips & tricks

./gradlew clean assemble check

./gradlew cl assem chec!

./gradlew assembleM75Debug // ?

./gradlew assemMDebu

./graldew aMD

BuildTypesandroid gradle plugin对每个项⺫⽬目都⾃自动设置了两个默认的buildType: debug | release!

android.buildTypes { debug { debuggable true applicationIdSuffix ".debug" // versionNameSuffix minifyEnabled true // runProguard true } jnidebug.initWith(buildTypes.debug) jnidebug { packageNameSuffix ".jnidebug" jniDebuggable true } }

Signing Configurationsandroid { signingConfigs { debug { storeFile file("path/to/debug.keystore") } customConfig { storeFile file("path/to/another.keystore") storePassword "android" keyAlias "customKey" keyPassword "android" } } buildTypes { custom { signingConfig singingConfigs.customConfig } } }

Proguardandroid { buildTypes { release { minifyEnabled true proguardFile getDefaultProguardFile('proguard-android.txt'), my-proguard-rule.txt, another-proguard-rule.pro } } productFlavors { flavor1 { } mx3 { proguardFile mx3-proguard-rules.pro } } }

Flavors

android.sourceSets.main { ... }!

android.productFlavors { flavor1 { versionCode 12 versionName "1.0" minSdkVersion 19 targetSdkVersion 20 applicationId "com.meizu.flyme.cloud" proguardFile "your/path/to/proguard-rules.txt" } }

android.sourceSets.main { ... }!

android.sourceSets.flavor1 { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] sets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] }

app/src/ |- main/ : |- res/ : |- java/ : |- res/ : |- AndroidManifest.xml : |- [aidl|assets|jni|rs etc.] |- flavor1/ |- res/ |- java/ |- res/ |- AndroidManifest.xml |- [aidl|assets|jni|rs etc.]

app/ |- build.gradle |- build/ |- libs/ |- src/ |- main/ : |- res/[drawable*|layout*|values*|menu] : |- java/ : |- res/ : |- AndroidManifest.xml : |- [aidl|assets|jni|rs etc.] |- androidTest/ |- [flavors|buildTypes folders] build/ [gradle/ | gradlew | gradlew.bat][build.gradle | settings.gradle]

android.productFlavors { mx3 { } m75 { } }!

Flavor! Debug(buildType)! Release(buildType) MX3! ! ! MX3Debug! ! ! MX3Release MX3! ! ! MX3Debug! ! ! MX3Release M75! ! ! M75Debug! ! ! M75Release M75! ! ! M75Debug! ! ! M75Release!

./gradlew asM7R ?!

./gradlew assembleM75Release

<!-- 高德地图API eng key -->

<meta-data android:name="com.amap.api.v2.apikey" android:value="@string/amap_key" />!

src/MX3/res/values/string.xml <string name="amap_key" translatable="false">1450abc101adb0148004445626ad****</string>!

src/M75/res/values/string.xml <string name="amap_key" translatable="false">635452f594448d8ca0465fed1007****</string>!

buildTypes同样src/debug/res/values/string.xml src/release/res/values/string.xml

-src |-debug |-res |-values |-strings.xml |-main |-res |-values |-strings.xml |-M75 |-res |-values |-strings.xml

flavorGroup: 参⻅见gradle flavor.pdf文档

Build Variants

Variant = flavorGroup* + buildType!

Application Variant | Library Variant Test Variant

Variant -> mx3ArmEngDebug!

优先级: mx3 > arm > eng > debug+defaultConfig!

./gradlew assembleMx3ArmEngDebug

android.applicationVariants.each { variant -> ....}!

def plugin = project.plugins.findPlugin('android') ?: project.plugins.findPlugin('android-library') def variants = plugin.class.name.endsWith('.LibraryPlugin') ? libraryVariants : applicationVariants variants.all { variant -> variant.packageApplication?.doFirst { if (gradleAfter(1.8) ) { def shouldPackageSo = 'true' == project.properties.get('unpackageSo') android.sourceSets.main.jniLibs.srcDirs = shouldPackageSo ? android.sourceSets.main.jniLibs.srcDirs << ['libs'] : [] } } }

New task

task clearJar(type: Delete) { delete 'outputs/shared_sdk.jar' } task makeJar(type: Copy) { from('build/intermediates/bundles/release') into('outputs/') include('classes.jar') rename ('classes.jar', 'shared_sdk.jar') } makeJar.dependsOn(clearJar, build)

pre* generate* … *dex …

assemble*

makeJar

dependsOn

yourTask

yourTask

task <-> tasks.createtask aTask(type: SomeType) {}tasks.create(name: 'aTask', type: SomeType){} task ('aTask', type: SomeType) {}!

task常用type: Copy: org.gradle.api.tasks.Copy Delete: org.gradle.api.tasks.Delete Compile, JavaCompile!

android常用task type: packageApplication

aTask.doFirst { // do something first }!

aTask.doLast { // do something last } aTask<< { // do something last }

Gradle Plugin

TODO

References

Gradle docs chapter 58 to 60!

[Android gradle plugin user guide](http://tools.android.com/tech-docs/new-build-system/user-guide)!

[Gradle custom plugin](http://code4reference.com/2012/08/gradle-custom-plugin-part-1/)

–刘俊

“The End”

top related