擁抱Android Studio(二):Android Studio與Gradle深入

jopen 9年前發布 | 67K 次閱讀 Android開發 移動開發 Android Studio

關于學習方式

曾經跟朋友討論過我們所接受過的大學工科教育,都是一上來先學基礎理論,最后再來一個金工實習。一開始不知道為什么而學,學不進去,荒廢了基礎,等到金工實習的時候,又發現基礎不牢,后悔不已。 考慮到傳統教育方式的不足之處,筆者在組織本系列文章的時候是先講入門實例,進而學習 Gradle 和 Groovy 基礎原理,最后學習進階實例。

上篇文章介紹了 從 ADT 遷移到 Android Studio ,相信經過很短時間的使用之后,已經開始熟悉和愛上 Android Studio 了。基礎的功能我就不講了,下面列舉一些較為深入又比較實用的功能。

Android Studio 相關功能介紹

文件夾組織視圖

最常用的有 Project 和 Android 視圖,前者按照項目文件樹進行組織,后者是以 Gradle 構建文件作為核心進行組織:

擁抱Android Studio(二):Android Studio與Gradle深入

Gradle 相關文件結構

讓我們來觀察一下Android Studio 中 Gradle 相關的結構:

.
├── 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 Cache

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

Multiple Language Editor

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

Gradle 相關功能介紹

Gradle View

點擊紅色三角運行按鈕,其實是執行了 Gradle 的 一些列任務,如果你想分別執行一些任務,則可以從 Gradle View 里面查看:

擁抱Android Studio(二):Android Studio與Gradle深入

命令行

工作區下方,有一個叫做 Terminal 的 tab,點擊之后,會自動 cd 到當前 project 根目錄下,可以輸入如下命令來嘗試下:

./gradlew build

Windows 下應該是 gradlew.bat build,下面均以 Mac 為例,不再贅述

可使用 help 參數來查看有哪些選項:

./gradlew --help

下面介紹一些重要的選項:

  • 查看運行 log

有些時候,一個任務運行失敗,只給出一個錯誤,沒有給具體原因,你就需要查看更多信息,可以使用參數 --info 或者 --stacktrace:

./gradlew build --info
  • 指定 module 或者 build.gradle

Gradle 默認是當前目錄下尋找 build.gradle 文件執行任務,這樣執行 build 會使得整個 project 所有的 module 的 build 任務都會運行,浪費不必要的時間,可以指定 module (-p) 或者 build.gradle (-b)文件以縮小作用范圍:

./gradlew -p app build

Sync

正常情況下,修改了 build.gradle 文件,文件上方就會有一個 sync 的按鈕,點擊之后會重新構建整個 build.gradle。但是某些特殊情況,這個同步可能會失敗。那就需要一個額外的觸發。

方法有四:

  • 再修改一下文件,便會再次出現 sync 按鈕
  • 點擊上方工作區的按鈕

擁抱Android Studio(二):Android Studio與Gradle深入

  • 點擊 Gradle View 中的同步按鈕

擁抱Android Studio(二):Android Studio與Gradle深入

  • 命令行執行一次 build

Build Variant

首先要了解兩個概念:

Build Type

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

Product Flavor

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

Build Variant = Build Type x Product Flavor

配置好了Build Type 和 Product Flavor 之后,Gradle 會生成若干個包,分別為:

payDebug
payRelease
freeDebug
freeRelease

配置實例

擁抱Android Studio(二):Android Studio與Gradle深入

假設這兩個版本的 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 上的私有空間,也可以是內網服務器上,甚至可以是本機磁盤上。

下面是本人使用的倉庫的一個例子:

allprojects {
    repositories {
        jcenter()
        mavenCentral()
        maven {
            url 'file:///Users/myusername/repo/'
        }
    }
}

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

遇到的坑

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

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

連接 jcenter 庫默認使用 https 協議,出現這個錯,多數情況下都是因為連接失敗了,原因嘛,你懂的。 可以嘗試將 jcenter 改成默認使用 http 連接:

jcenter {
            url "http://jcenter.bintray.com/"
        }

下載不到特定的版本

Maven 和 Gradle 都會有一個緩存庫,默認安裝的情況下,是在用戶根目錄下的 .m2 或者 .gradle 文件夾中。 可以嘗試刪除里面的文件。例如將 Gradle 的 cache 文件刪除:

rm -rf ~/.gradle/caches/

注意:這個操作可能會導致所有的遠程庫都需要重新下載,要三思后行。

庫重復沖突

筆者的包使用了 com.android.support:support-v4:19.0.0 包,可能用戶的 App 也使用了這個包,就可能在編譯進行代碼合并到時候出類似的錯:

UNEXPECTED TOP-LEVEL EXCEPTION
multiple dex files define Landroid/support/annotation/AniRes

這個時候,在 module 的 build.gradle 的 dependency 添加依賴時,加入 exclude 規則:

compile ('com.bugtags.library:bugtags-lib:latest.integration') {
        exclude group: 'com.android.support', module: 'support-v4'
}

后續引言

講到這里,有些讀者可能會遇到跟我當時開始使用 Gradle 一樣的問題:遇到問題就 Stack Overflow,找到 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 有說明。

理解了以上基礎之后,你就會知其然,知其所以然了。

以上知識,下一篇將會詳細介紹。敬請留意。

本文所使用的 demo 已經上傳到了 github 中,可以參閱 embrace-android-studio-demo

參考文獻

系列導讀

本文是筆者《擁抱 Android Studio》系列第二篇,其他篇請點擊:

擁抱Android Studio(二):Android Studio與Gradle深入 作者簡介:

何暢彬,BugTags技術總監,關注移動SDK研發、后端服務設計與實現,個人博客: http://kvh.io/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!