Android Studio :Android Studio 與 Gradle 深刻【二】

轉載:http://www.apkbus.com/forum.php?mod=viewthread&tid=255063&extra=page%3D2%26filter%3Dauthor%26orderby%3Ddateline&_dsign=55ac1be3

Android Studio 相關功能介紹文件夾組織視圖php

最經常使用的有 Project 和 Android 視圖,前者按照項目文件樹進行組織,後者是以 Gradle 構建文件做爲核心進行組織:
 
Project 視圖與 Android 視圖
 

Gradle 相關文件結構java

讓咱們來觀察一下Android Studio 中 Gradle 相關的結構:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.
├── gradle
│   └── wrapper                                //所使用的 Gradle 包裝器配置
├── .gradle                                        //所使用 Gradle 版本
│   └── 2.8
├── AsInDepth.iml
├── app                                                //app module
│   ├── app.iml
│   ├── build
│   ├── build.gradle                //app module 的 build.gradle
│   ├── libs
│   ├── proguard-rules.pro
│   └── src
├── build.gradle                        //項目 build.gradle,一般配置項目全局配置,如 repositories 和 dependencies
├── gradle.properties                //項目屬性文件,一般能夠放置一些常量
├── gradlew                                        //Gradle 包裝器可執行文件
├── gradlew.bat                                //Gradle 包裝器可執行文件(Windows)
├── lib                                                //lib module
│   ├── build
│   ├── build.gradle                //lib module 的 build.gradle
│   ├── lib.iml
│   ├── libs
│   ├── proguard-rules.pro
│   └── src
├── local.properties                //項目的本地屬性,一般是 sdk 所在位置
└── settings.gradle                        //項目整體設置,一般是配置項目中全部的 module


Invalidate Cacheandroid

Android Studio 會出現索引的問題,那能夠從刪除 cache 重建索引,File->Invalidate Caches/Restart
 

Multiple Language Editorgit

多語言文字能夠經過右擊文件 Open Translation Editor,能夠同時進行編輯,可是我發現若是把 strings.xml 改了別的名字,這個功能就不 work 了。
 

Gradle 相關功能介紹Gradle Viewgithub

點擊紅色三角運行按鈕,實際上是執行了 Gradle 的 一些列任務,若是你想分別執行一些任務,則能夠從 Gradle View 裏面查看:
 
gradle view
 

命令行編程

工做區下方,有一個叫作 Terminal 的 tab,點擊以後,會自動 cd 到當前 project 根目錄下,能夠輸入以下命令來嘗試下:
 
1 ./gradlew build

 

Windows 下應該是 gradlew.bat build,下面均以 Mac 爲例,再也不贅述
 
可以使用 help 參數來查看有哪些選項:
 
1 ./gradlew --help

 

下面介紹一些重要的選項:
 
  • 查看運行 log

 

有些時候,一個任務運行失敗,只給出一個錯誤,沒有給具體緣由,你就須要查看更多信息,可使用參數 –info 或者 –stacktrace:
 
1 ./gradlew build --info

 

  • 指定 module 或者 build.gradle

 

Gradle 默認是當前目錄下尋找 build.gradle 文件執行任務,這樣執行 build 會使得整個 project 全部的 module 的 build 任務都會運行,浪費沒必要要的時間,能夠指定 module (-p) 或者 build.gradle (-b)文件以縮小做用範圍:
 
1 ./gradlew -p app build


Sync緩存

正常狀況下,修改了 build.gradle 文件,文件上方就會有一個 sync 的按鈕,點擊以後會從新構建整個 build.gradle。可是某些特殊狀況,這個同步可能會失敗。那就須要一個額外的觸發。
方法有四:
 
  • 再修改一下文件,便會再次出現 sync 按鈕
  • 點擊上方工做區的按鈕

 

sync button top
 
  • 點擊 Gradle View 中的同步按鈕

 

sync button top
 
  • 命令行執行一次 build


Build Variant服務器

首先要了解兩個概念:
 

Build Type閉包

分爲 debug 和 release,這個概念容易懂
 

Product Flavorapp

這個概念主要是爲了知足以下需求:同一份代碼要打多個包,例如收費 pay 和免費 free,邏輯上有一些小區別,又不想經過邏輯判斷這種醜陋的方式。或者你要實現所謂多渠道打包。

Build Variant = Build Type x Product Flavor

配置好了Build Type 和 Product Flavor 以後,Gradle 會生成若干個包,分別爲:
 
1
2
3
4
payDebug
payRelease
freeDebug
freeRelease


配置實例

build variant
 
假設這兩個版本的 app,有一個類 DiffBean 須要作大量的邏輯判斷,則能夠經過在 build.gradle 中配置 product flavor,在代碼中添加兩個與 main 平齊的文件夾,
把 DiffBean 從 main 中抽出來,分別放在兩個文件夾中,只關注對應的邏輯便可。
 
關於 Product Flavor 中都能定義哪些屬性,請參考 Android Gradle DSL
 

Gradle 使用的倉庫

要使用遠程依賴,就得有個庫的倉庫,Gradle 支持 maven 倉庫。這些庫能夠是公用的,例如 mavenCentral 或者 jcenter,也可使用私有庫。
筆者曾經上傳過公用庫到 mavenCentral 和 jcenter,前者的繁瑣與難以管理,讓人深惡痛絕。Android Studio 在0.8.0版本之後,將 jcenter 做爲默認的 maven 庫公用庫來源。
私有庫能夠託管在任何一個能訪問到的地方,能夠託管在 bintray 上的私有空間,也能夠是內網服務器上,甚至能夠是本機磁盤上。
下面是本人使用的倉庫的一個例子:
 
1
2
3
4
5
6
7
8
9
allprojects {
    repositories {
        jcenter()
        mavenCentral()
        maven {
            url 'file:///Users/myusername/repo/'
        }
    }
}

 

關於庫,會在本系列的四篇會有更詳細的敘述。
 

使用 jni 預編譯 .so 庫

  • 默認狀況下,能夠放在與 java 平級的 jniLibs 文件夾中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .
    ├── AndroidManifest.xml
    ├── java
    │   └── io
    │       └── kvh
    ├── jniLibs
    │   ├── armeabi
    │   │   └── libweibosdkcore.so
    │   └── armeabi-v7a
    │       └── libweibosdkcore.so
    └── res
  • 不少人喜歡放在與 src 平級的 libs 文件夾中
    1
    2
    3
    4
    5
    6
    7
    8
    ├── build.gradle
    ├── libs
    │   ├── armeabi
    │   │   └── libweibosdkcore.so
    │   └── armeabi-v7a
    │       └── libweibosdkcore.so
    ├── proguard-rules.pro
    └── src
    這樣須要在 build.gradle 文件添加以下說明:
    1
    2
    3
    4
    5
    6
    android {
       sourceSets {
           main {
               jniLibs.srcDirs = ['libs']
           }
       }

升級 gradle 插件

  • 在 bintray 上查找最新的版本
  • 修改項目的 build.gradle 中插件的版本
    1
    2
    3
    4
    5
    6
    7
    8
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.0.0-alpha5'//這裏
        }
    }
  • 若是有提示錯誤,則可能須要 gradle 的運行環境版本,修改項目根目錄下文件 gradle/wrapper/gradle-wrapper.properties 中的 distributionUrl爲最新,例如
    1 distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

遇到的坑

所在的項目的包已經發布到了 mavenCentral 和 jcenter,不少用戶的在集成的時候,遇到問題,其中最經典的問題,即是下面的三個。
 

下載依賴庫失敗,報 peer not found

鏈接 jcenter 庫默認使用 https 協議,出現這個錯,多數狀況下都是由於鏈接失敗了,緣由嘛,你懂的。
能夠嘗試將 jcenter 改爲默認使用 http 鏈接:
 
1
2
3
jcenter {
            url "http://jcenter.bintray.com/"
        }

下載不到特定的版本

Maven 和 Gradle 都會有一個緩存庫,默認安裝的狀況下,是在用戶根目錄下的 .m2 或者 .gradle 文件夾中。
能夠嘗試刪除裏面的文件。例如將 Gradle 的 cache 文件刪除:
 
1 rm -rf ~/.gradle/caches/

 

注意這個操做可能會致使全部的遠程庫都須要從新下載,要三思後行。

庫重複衝突

筆者的包使用了 com.android.support:support-v4:19.0.0 包,可能用戶的 app 也使用了這個包,就可能在編譯進行代碼合併到時候出相似的錯:
 
1
2
UNEXPECTED TOP-LEVEL EXCEPTION
multiple dex files define Landroid/support/annotation/AniRes

 

這個時候,在 module 的 build.gradle 的 dependency 添加依賴時,加入 exclude 規則:
 
1
2
3
compile ('com.bugtags.library:bugtags-lib:latest.integration') {
        exclude group: 'com.android.support', module: 'support-v4'
}


後續引言

講到這裏,有些讀者可能會遇到跟我當時開始使用 Gradle 同樣的問題:遇到問題就 stackoverflow,找到 workaround 了但不知道爲何,gradle 版本更新了,發現不 work 了,甚爲惆悵。
究其緣由,都是不理解基礎。下面扼要勾勒個大概。
首先 Gradle 是一個構建平臺,它使用的是 Groovy 語言。
Groovy是一種基於 Java 的語言,提供了更好的動態特性,可使用閉包使得編程更靈活,很適合作腳本語言。
上面提到的 settings.gradle 和 build.gradle 在 Gradle 平臺中,其實都是一個 Groovy 對象。
Gradle 經過插件(plugin)的方式來支持構建。插件是不少任務(task)的集合,task 中又包含了許多 action。
而例如 productFlavors 都是一個所謂的 DSL,插件都定義了不少的 DSL,我理解的所謂的 DSL 就是一個小語言規範用來處理一個特定的事情(大多狀況下是配置)。Android 的插件的 DSL 文檔在 Android Gradle DSL 有說明。
理解了以上基礎以後,你就會知其然,知其因此然了。
相關文章
相關標籤/搜索