Gradle for Android 使用之旅之gradle的基礎

Gradle Build Files in Android 第一章

Gradle for Android Basics

Android applications 使用gradle構建,gradle是一門高級語言并且廣泛用于java中,提供的Android插件為Android apps開發提供了很多的功能,例如build types, flavors, signing configurations, library projects,更多可查看Android Plugin DSL Reference

1.1 Gradle Build Files in Android

問題

你想理解創建Android工程生成的build file

解決方案

創建一個新的Android工程并查看settings.gradle, build.gradle, 和 app/build.gradle.

分析

Android Studio 是官方提供開發Android projects 的IDE,通過Android Studio 向導Start a new Android Studio project創建第一個項目吧。

Start a new Android Studio project
Start a new Android Studio project

這一步就不多說了,相信大家都知道的。

然后我們看到一個默認的工程是怎么樣的。

default project view
default project view

settings.gradle

Gradle 構建的Android工程是一個多項目工程,在settings.gradle中顯示當前項目有哪些module。默認顯示:

    include ':app'

如果這時我創建一個名為gradledemomodule 的library項目

new library
new library

settings.gradle會增加gradledemomodule,多個項目用,隔開,顯示如下:

    include ':app', ':gradledemomodule'

project的build.gradle

    buildscript {
      repositories {
        jcenter()
      }
      dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
      }
    }

    allprojects {
      repositories {
        jcenter()
      }
    }

    task clean(type: Delete) {
      delete rootProject.buildDir
    }

首先來看下buildscript節點,他是gradle腳本自身需要使用的資源,資源下載來自jcenter倉庫,關于jcenterMaven單獨去了解。jcenter目前是默認的,他兼容了Maven并且性能更優。然后在dependencies節點中聲明了我們使用的gradle版本。

或許我們會以為allprojects中也同樣聲明了jcenter是否是重復了,其實不是的allprojects設置所有project默認的倉庫來源,與buildscript作用范圍是不一樣的。

task clean聲明了一個任務,任務類型是Delete(也可以是copy等),每當修改settings.gradle后同步則會刪除rootProject.buildDir目錄下所有。

app的build.gradle

    apply plugin: 'com.android.application'

    android {
      compileSdkVersion 24
      buildToolsVersion "23.0.3"

      defaultConfig {
        applicationId "com.branch.www.gradledemo"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
      }

      buildTypes {
        release {
          minifyEnabled false
          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
      }
    }

    dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      testCompile 'junit:junit:4.12'
      compile 'com.android.support:appcompat-v7:24.1.1'
    }

這個目錄下的build.gradle 是開發過程中最重要的,首先看到apply plugin: 'com.android.application',他的作用是把Android插件加入到當前build工程,相應的插件功能可看上一個DSL

android節點則是一些Android的配置,例如app 版本,編譯sdk,包名,混淆配置,多渠道等。

dependencies節點是幫助我們添加項目依賴,并且通過上一個.gradle知道默認倉庫是jcenter

1.2 配置SDK版本以及其他

問題

你想要設置最低和目標Android SDK版本或者是否混淆等。

解決方法

修改當前build.gradle中android節點中的配置。

分析

android節點是配置app相關的屬性。

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
            defaultConfig {
                applicationId "com.kousenit.myandroidapp"
                minSdkVersion 19
                targetSdkVersion 23
                versionCode 1
                versionName "1.0"
            }
        compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    }

這些參數大多在AndroidManifest.xml遺棄,現在在build.gradle中使用。

Configure_SDK_Versions_1.png
Configure_SDK_Versions_1.png
Configure_SDK_Versions_2.png
Configure_SDK_Versions_2.png

1.3 在控制臺執行gradle build

問題

你想通過命令run gradle tasks.

解決方法

在控制臺運行它。

分析

你不需要為了build Android project 而去下載安裝gradle ,因為項目中已經配置好了。直接在Android Studio的terminal中執行。

terminal-build
terminal-build

windows下輸入gradlew build即可。

在控制臺你可以運行任何gradle支持的task,包含自定義的task,輸入gradlew tasks會列出項目中所有 task。這份報告顯示項目中所有的默認 task 以及每個 task 的描述。

額外的功能和控制臺標記

  • 使用空格分開使一次run多個task。如:

      >gradlew lint hello
    

    lint是自帶的,hello是我自己寫的,這樣就會執行lint后再執行hello.

    gradlew-multiple-tasks
    gradlew-multiple-tasks

    同時你會發現相同名字的task在一次執行中只會執行一遍

  • 使用-x標記排除task

      >gradlew lint -x hello
    

    這一次執行只會執行lint而不會執行hello。

  • 發生故障時繼續構建 --continue

    默認情況下,只要任何 task 失敗,Gradle 將中止執行。這使得構建更快地完成,但隱藏了其他可能發生的故障。為了發現在一個單一的構建中多個可能發生故障的地方,你可以使用 --continue 選項。

  • 任務名稱縮寫

    例如我創建一個名為greet的task,在控制臺輸入>gradlew g也可以執行,也就當你試圖執行某個 task 的時候,無需輸入 task 的全名.只需提供足夠的可以唯一區分出該 task 的字符即可

  • 選擇要執行的構建

    調用 gradle 命令時,默認情況下總是會在當前目錄下尋找構建文件(譯者注:首先會尋找當前目錄下的 build.gradle 文件,以及根據settings.gradle 中的配置尋找子項目的 build.gradle )。 可以使用 -b 參數選擇其他的構建文件,并且當你使用此參數時 settings.gradle 將不會被使用,看下面的例子:

      app/demo.gradle
    
          task demohello <<{
    
          println "hello demo gradle"
      }
    

    在app目錄下我又創建了一個demo.gradle,如果想要執行demo.gradle中的task可以使用-b,如:

      gradlew -b app/demo.gradle demohello
    

    如果不想使用-b 可以使用applydemo.gradle加入到當前build.gradle

      apply plugin: 'com.android.application'
         apply from: 'demo.gradle'
    

    如果這樣配置后執行是直接使用task名。

  • 顯示 task 使用細節

    執行 gradle help --task someTask 可以獲取到 task 的詳細信息, 或者多項目構建中相同 task 名稱的所有 task 的信息,如下

      Detailed task information for demohello
                               
      Path                 
           :app:demohello  
                               
      Type                 
           Task (org.gradle.api.Task)
                               
      Description          
           -               
                               
      Group                
           -               
                               
      BUILD SUCCESSFUL
    

1.4 使用Android Studio執行Gradle Builds

問題

直接通過Android Studio 執行Gradle

解決方法

使用Gradle 視圖去執行tasks

分析

Android Studio 本身是帶有Gradle 視圖列出所有tasks.

Android Studio gradle view
Android Studio gradle view

選擇一個執行,雙擊或右鍵選擇執行

Android Studio gradle view-run
Android Studio gradle view-run

1.5 添加java library

問題

添加java library 到項目中

解決方法

build.gradledependencies添加

分析

默認的dependencies

    dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      testCompile 'junit:junit:4.12'
      compile 'com.android.support:appcompat-v7:24.1.1'
    }
  • dependencies基本語法

    library依賴完全的語法是 group:name:version

    • 完全語法:

      testCompile group: 'junit', name: 'junit', version: '4.12'

    • 簡寫語法:

      testCompile 'junit:junit:4.12'

    • 版本為變量的寫法(不推薦):

      testCompile 'junit:junit:4.+'

      只要版本大于等于4.0的都可以。

    • jar包依賴:

      dependencies {
      compile files('libs/a.jar', 'libs/b.jar')
      compile fileTree(dir: 'libs', include: '*.jar')
      }

Synchronizing the project

每次更改.gradle后需要同步整個項目,通常IDE會在頂部提示:

sync_now_1
sync_now_1

sync_now_2
sync_now_2

同步時會到倉庫去下載依賴包。

Transitive dependencies

間接依賴是指在依賴的A中同時A又依賴了B,那么依賴就會同時下載A,B到項目中,而如果在你的項目中你本身就依賴了B則會出現jar包沖突
可在控制臺執行androidDependenciestask查看間接依賴。

間接依賴默認是允許的,可以通過transitive關閉,例如:

    dependencies {
    runtime group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.0.1',
    transitive: false
    }

或,只需要groovy-all本身的jar包,不需要間接依賴的。

    dependencies {
        compile 'org.codehaus.groovy:groovy-all:2.4.4@jar'
    }

    dependencies {
        compile group: 'org.codehaus.groovy', name: 'groovy-all',
           version: '2.4.4', ext: 'jar'
    }

如果是aar則把@jar換成@aar。

Excluding dependencies

如果一個library中有我們不需要的包,則可以通過exclude移除。

    androidTestCompile('com.android.support:appcompat-v7:24.1.1') {
    exclude group: 'support-vector-drawable'
    exclude group: 'animated-vector-drawable'
    }

1.6 通過Android Studio 添加依賴包

問題

使用Android Studio添加依賴,而不是直接使用build.gradle

解決方案

在項目設置中的Dependencies選擇依賴lib

分析

打開項目設置,選擇Dependencies

dependencies_1
dependencies_1

同時Dependencies提供了6中依賴作用范圍:

  • Compile

    compile是對所有的build type以及favlors都會參與編譯并且打包到最終的apk文件中。

  • Provided

    Provided是對所有的build type以及favlors只在編譯時使用,類似eclipse中的external-libs,只參與編譯,不打包到最終apk。

  • APK

    只會打包到apk文件中,而不參與編譯,所以不能再代碼中直接調用jar中的類或方法,否則在編譯時會報錯

  • Test compile

    Test compile 僅僅是針對單元測試代碼的編譯編譯以及最終打包測試apk時有效,而對正常的debug或者release apk包不起作用。

  • Debug compile

    Debug compile 僅僅針對debug模式的編譯和最終的debug apk打包。

  • Release compile

    Release compile 僅僅針對Release 模式的編譯和最終的Release apk打包。

依賴的方式有三種,倉庫依賴,文件依賴,module依賴。

dependencies_2
dependencies_2

1.7 Configuring Repositories

問題

你想要gradle 準確的實現任何library依賴。

解決方法

配置repositories節點

分析

  • Declaring Repositories

    repositories中告訴gradle到哪里去找到依賴,通常我們都是使用jcenter()

      repositories {
          jcenter()
      }
    

    jcenter 倉庫在https://jcenter.bintray.com/

    同時我們也可以使用maven 地址:http://repo1.maven.org/maven2

      repositories {
          mavenLocal()
          mavenCentral()
      }
    

    maven 支持在本地發布倉庫,然后使用。

    maven 也能通過url加載依賴。

      repositories {
      maven {
          url 'http://repo.spring.io/milestone'
      }
      }
    

    如果倉庫有保護,可以使用username,password

      repositories {
      maven {
          credentials {
              username 'username'
              password 'password'
          }
          url 'http://repo.mycompany.com/maven2'
          }
      }
    

    使用lvy 倉庫

      repositories {
          ivy {
              url 'http://my.ivy.repo'
          }
      }
    

    使用本地目錄作為倉庫

      repositories {
          flatDir {
      dirs 'lib' }
      }
    

第二章:從創建項目到發布

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容