日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Gradle使用总结

發(fā)布時間:2024/9/30 Android 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Gradle使用总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/zhaoyanjun6/article/details/77678577
本文出自【趙彥軍的博客】

系列目錄

Android Gradle使用總結(jié)
Android Studio 插件開發(fā)詳解一:入門練手
Android Studio 插件開發(fā)詳解二:工具類
Android Studio 插件開發(fā)詳解三:翻譯插件實(shí)戰(zhàn)
Android Studio 插件開發(fā)詳解四:填坑
Android Gradle 自定義Task 詳解
Android Gradle 自定義Task詳解二:進(jìn)階

文章目錄

    • 系列目錄
    • Android Gradle
    • Android Gradle 的 Project 和 Tasks
    • Android Gradle 構(gòu)建生命周期
    • 認(rèn)知Gradle Wrapper
    • Android 三個文件重要的 gradle 文件
    • 定制項(xiàng)目屬性(project properties)
    • Android studio gradle Task
    • lint 檢測
    • buildTypes 定義了編譯類型
    • productFlavors 多渠道打包
    • 多渠道設(shè)置包名
    • Signing 簽名
    • 依賴管理
      • 1、依賴 jcenter 包
      • 2、依賴本地 module
      • 3、依賴 jar 包
      • 4、依賴 aar 包
      • 5、自定義依賴包目錄
      • 6、依賴配置
      • 7、排除依賴兼容包
    • native包(so包)
    • defaultConfig 詳解
      • resConfigs : 過濾語言
      • resConfigs : 過濾 drawable文件夾的資源
    • buildTypes 詳解
      • initWith :復(fù)制屬性
      • applicationIdSuffix 、versionNameSuffix :添加后綴
      • buildConfigField: 自定義屬性
    • Gradle 實(shí)現(xiàn)差異化構(gòu)建
      • 情景1
      • 情景2
    • SourceSet
      • SourceSet 簡介
      • SourceSet 定義源碼目錄
      • SourceSet 定義資源目錄
      • SourceSet 實(shí)現(xiàn) layout 分包
      • SourceSet 定義 AndroidManifest 文件
      • SourceSet 定義 assets 目錄
      • SourceSet 定義其他資源
    • applicationVariants
      • 定義 versionName 、VersionCode
      • 定義 APK 包的名字
    • Task
      • 定義 task
      • mustRunAfter 定義 task 執(zhí)行順序
      • dependsOn 定義 task 依賴
    • 常用 Gradlew 命令
    • Gradle 日志管理
      • Log 等級
      • 改變默認(rèn)輸出
    • 參考資料

Groovy 使用完全解析 http://blog.csdn.net/zhaoyanjun6/article/details/70313790

Android Gradle

Android項(xiàng)目使用 Gradle 作為構(gòu)建框架,Gradle 又是以Groovy為腳本語言。所以學(xué)習(xí)Gradle之前需要先熟悉Groovy腳本語言。

Groovy是基于Java語言的腳本語言,所以它的語法和Java非常相似,但是具有比java更好的靈活性。下面就列舉一些和Java的主要區(qū)別。

Android Gradle 的 Project 和 Tasks

這個Gradle中最重要的兩個概念。每次構(gòu)建(build)至少由一個project構(gòu)成,一個project 由一到多個task構(gòu)成。項(xiàng)目結(jié)構(gòu)中的每個build.gradle文件代表一個project,在這編譯腳本文件中可以定義一系列的task;task 本質(zhì)上又是由一組被順序執(zhí)行的Action`對象構(gòu)成,Action其實(shí)是一段代碼塊,類似于Java中的方法。

Android Gradle 構(gòu)建生命周期

每次構(gòu)建的執(zhí)行本質(zhì)上執(zhí)行一系列的Task。某些Task可能依賴其他Task。哪些沒有依賴的Task總會被最先執(zhí)行,而且每個Task只會被執(zhí)行一遍。每次構(gòu)建的依賴關(guān)系是在構(gòu)建的配置階段確定的。每次構(gòu)建分為3個階段:

  • Initialization: 初始化階段

這是創(chuàng)建Project階段,構(gòu)建工具根據(jù)每個build.gradle文件創(chuàng)建出一個Project實(shí)例。初始化階段會執(zhí)行項(xiàng)目根目錄下的settings.gradle文件,來分析哪些項(xiàng)目參與構(gòu)建。

所以這個文件里面的內(nèi)容經(jīng)常是:

include ':app' include ':libraries:someProject'

這是告訴Gradle這些項(xiàng)目需要編譯,所以我們引入一些開源的項(xiàng)目的時候,需要在這里填上對應(yīng)的項(xiàng)目名稱,來告訴Gradle這些項(xiàng)目需要參與構(gòu)建。

  • Configuration:配置階段

這個階段,通過執(zhí)行構(gòu)建腳本來為每個project創(chuàng)建并配置Task。配置階段會去加載所有參與構(gòu)建的項(xiàng)目的build.gradle文件,會將每個build.gradle文件實(shí)例化為一個Gradle的project對象。然后分析project之間的依賴關(guān)系,下載依賴文件,分析project下的task之間的依賴關(guān)系。

  • Execution:執(zhí)行階段

這是Task真正被執(zhí)行的階段,Gradle會根據(jù)依賴關(guān)系決定哪些Task需要被執(zhí)行,以及執(zhí)行的先后順序。
task是Gradle中的最小執(zhí)行單元,我們所有的構(gòu)建,編譯,打包,debug,test等都是執(zhí)行了某一個task,一個project可以有多個task,task之間可以互相依賴。例如我有兩個task,taskA和taskB,指定taskA依賴taskB,然后執(zhí)行taskA,這時會先去執(zhí)行taskB,taskB執(zhí)行完畢后在執(zhí)行taskA。

說到這可能會有疑問,我翻遍了build.gradle也沒看見一個task長啥樣,有一種被欺騙的趕腳!

其實(shí)不是,你點(diǎn)擊AndroidStudio右側(cè)的一個Gradle按鈕,會打開一個面板,內(nèi)容差不多是這樣的:

里面的每一個條目都是一個task,那這些task是哪來的呢?

一個是根目錄下的 build.gradle 中的

dependencies {classpath 'com.android.tools.build:gradle:2.2.2'}

一個是 app 目錄下的 build.gradle 中的

apply plugin: 'com.android.application'

這兩段代碼決定的。也就是說,Gradle提供了一個框架,這個框架有一些運(yùn)行的機(jī)制可以讓你完成編譯,但是至于怎么編譯是由插件決定的。還好Google已經(jīng)給我們寫好了Android對應(yīng)的Gradle工具,我們使用就可以了。

根目錄下的build.gradle中dependencies {classpath ‘com.android.tools.build:gradle:2.2.2’}是Android Gradle編譯插件的版本。

app目錄下的build.gradle中的apply plugin: 'com.android.application’是引入了Android的應(yīng)用構(gòu)建項(xiàng)目,還有com.android.library和com.android.test用來構(gòu)建library和測試。

所有Android構(gòu)建需要執(zhí)行的task都封裝在工具里,如果你有一些特殊需求的話,也可以自己寫一些task。那么對于開發(fā)一個Android應(yīng)用來說,最關(guān)鍵的部分就是如何來用AndroidGradle的插件了。

認(rèn)知Gradle Wrapper

Android Studio中默認(rèn)會使用 Gradle Wrapper 而不是直接使用Gradle。命令也是使用gradlew而不是gradle。這是因?yàn)間radle針對特定的開發(fā)環(huán)境的構(gòu)建腳本,新的gradle可能不能兼容舊版的構(gòu)建環(huán)境。為了解決這個問題,使用Gradle Wrapper 來間接使用 gradle。相當(dāng)于在外邊包裹了一個中間層。對開發(fā)者來說,直接使用Gradlew 即可,不需要關(guān)心 gradle的版本變化。Gradle Wrapper 會負(fù)責(zé)下載合適的的gradle版本來構(gòu)建項(xiàng)目。

Android 三個文件重要的 gradle 文件

Gradle項(xiàng)目有3個重要的文件需要深入理解:項(xiàng)目根目錄的 build.gradle , settings.gradle 和模塊目錄的 build.gradle 。

  • 1.settings.gradle 文件會在構(gòu)建的 initialization 階段被執(zhí)行,它用于告訴構(gòu)建系統(tǒng)哪些模塊需要包含到構(gòu)建過程中。對于單模塊項(xiàng)目, settings.gradle 文件不是必需的。對于多模塊項(xiàng)目,如果沒有該文件,構(gòu)建系統(tǒng)就不能知道該用到哪些模塊。

  • 2.項(xiàng)目根目錄的 build.gradle 文件用來配置針對所有模塊的一些屬性。它默認(rèn)包含2個代碼塊:buildscript{…}和allprojects{…}。前者用于配置構(gòu)建腳本所用到的代碼庫和依賴關(guān)系,后者用于定義所有模塊需要用到的一些公共屬性。

buildscript {repositories {jcenter()}dependencies {classpath 'com.android.tools.build:gradle:2.3.2'} }allprojects {repositories {jcenter()} }task clean(type: Delete) {delete rootProject.buildDir }

buildscript:定義了 Android 編譯工具的類路徑。repositories中, jCenter是一個著名的 Maven 倉庫。

allprojects:中定義的屬性會被應(yīng)用到所有 moudle 中,但是為了保證每個項(xiàng)目的獨(dú)立性,我們一般不會在這里面操作太多共有的東西。

  • 3.模塊級配置文件 build.gradle 針對每個moudle 的配置,如果這里的定義的選項(xiàng)和頂層 build.gradle定義的相同。它有3個重要的代碼塊:plugin,android 和 dependencies。

定制項(xiàng)目屬性(project properties)

在項(xiàng)目根目錄的build.gradle配置文件中,我們可以定制適用于所有模塊的屬性,通過ext 代碼塊來實(shí)現(xiàn)。如下所示:

ext {compileSdkVersion = 22buildToolsVersion = "22.0.1" }

然后我們可以在模塊目錄的build.gradle配置文件中引用這些屬性,引用語法為rootProject.ext.{屬性名}。如下:

android {compileSdkVersion rootProject.ext.compileSdkVersionbuildToolsVersion rootProject.ext.buildToolsVersion }

Android studio gradle Task

//構(gòu)建 gradlew app:clean //移除所有的編譯輸出文件,比如apkgradlew app:build //構(gòu)建 app module ,構(gòu)建任務(wù),相當(dāng)于同時執(zhí)行了check任務(wù)和assemble任務(wù)//檢測 gradlew app:check //執(zhí)行l(wèi)int檢測編譯。//打包 gradlew app:assemble //可以編譯出release包和debug包,可以使用gradlew assembleRelease或者gradlew assembleDebug來單獨(dú)編譯一種包gradlew app:assembleRelease //app module 打 release 包gradlew app:assembleDebug //app module 打 debug 包//安裝,卸載gradlew app:installDebug //安裝 app 的 debug 包到手機(jī)上gradlew app:uninstallDebug //卸載手機(jī)上 app 的 debug 包gradlew app:uninstallRelease //卸載手機(jī)上 app 的 release 包gradlew app:uninstallAll //卸載手機(jī)上所有 app 的包

這些都是基本的命令,在實(shí)際項(xiàng)目中會根據(jù)不同的配置,會對這些task 設(shè)置不同的依賴。比如 默認(rèn)的 assmeble 會依賴 assembleDebug 和assembleRelease,如果直接執(zhí)行assmeble,最后會編譯debug,和release 的所有版本出來。如果我們只需要編譯debug 版本,我們可以運(yùn)行assembleDebug。

除此之外還有一些常用的新增的其他命令,比如 install命令,會將編譯后的apk 安裝到連接的設(shè)備。

lint 檢測

  • 忽略編譯器的 lint 檢查
android {lintOptions {abortOnError false}}

buildTypes 定義了編譯類型

android{buildTypes {release {minifyEnabled true //打開混淆proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {minifyEnabled false //關(guān)閉混淆proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}}

productFlavors 多渠道打包

AndroidManifest.xml 里設(shè)置動態(tài)渠道變量

<meta-dataandroid:name="UMENG_CHANNEL"android:value="${UMENG_CHANNEL_VALUE}" />

在 build.gradle 設(shè)置 productFlavors , 這里假定我們需要打包的渠道為酷安市場、360、小米、百度、豌豆莢。

android { productFlavors {kuan {manifestPlaceholders = [UMENG_CHANNEL_VALUE: "kuan"]}xiaomi {manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]}qh360 {manifestPlaceholders = [UMENG_CHANNEL_VALUE: "qh360"]}baidu {manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]}wandoujia {manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]}} }

或者批量修改

android { productFlavors {kuan {}xiaomi {}qh360 {}baidu {}wandoujia {}} productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] } }

這樣在打包的時候就可以選擇渠道了

或者用命令打包 ,比如:

gradlew assembleWandoujiaRelease //豌豆莢 release 包gradlew assembleWandoujiaDebug //豌豆莢 debug 包

多渠道設(shè)置包名

有時候我們需要分渠道設(shè)置 applicationId 、友盟的 appkey 、友盟渠道號。

productFlavors {google {applicationId "com.wifi.cool"manifestPlaceholders = [ UMENG_APPKEY_VALUE : "456789456789",UMENG_CHANNEL_VALUE: "google", ]}baidu{applicationId 'com.wifi.hacker'manifestPlaceholders = [UMENG_APPKEY_VALUE : "123456789789",UMENG_CHANNEL_VALUE : "baidu", ]}}

Signing 簽名

在 android 標(biāo)簽下添加 signingConfigs 標(biāo)簽,如下:

android {signingConfigs {config {keyAlias 'yiba'keyPassword '123456'storeFile file('C:/work/Key.jks')storePassword '1234567'}}}

可以在 release 和 debug 包中定義簽名,如下:

android {signingConfigs {config {keyAlias 'yiba'keyPassword '123456'storeFile file('C:/work/Key.jks')storePassword '1234567'}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'signingConfig signingConfigs.config}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'signingConfig signingConfigs.config}} }

依賴管理

1、依賴 jcenter 包

每個庫名稱包含三個元素:組名:庫名稱:版本號

compile 'com.android.support:appcompat-v7:25.0.0'

2、依賴本地 module

compile project(':YibaAnalytics')

3、依賴 jar 包

  • 1、把 jar 包放在 libs 目錄下
  • 2、在 build.gradle 中添加依賴
dependencies {compile files('libs/YibaAnalytics5.jar') }

4、依賴 aar 包

  • 1、把 aar 包放到 libs 目錄下
  • 2、在 build.gradle 中添加依賴
repositories {flatDir {dirs 'libs'} }dependencies {compile(name:'YibaAnalytics-release', ext:'aar') }

如圖所示:

5、自定義依賴包目錄

當(dāng)我們的 aar 包需要被多個 module 依賴時,我們就不能把 aar 包放在單一的 module 中,我們可以在項(xiàng)目的根目錄創(chuàng)建一個目錄,比如叫 aar 目錄,然后把我們的 aar 包放進(jìn)去,如圖所示:

在項(xiàng)目的根目錄的 build.gradle 的 allprojects 標(biāo)簽下的 repositories 添加 :

flatDir {dirs '../aar' }

../aar 表示根目錄下的 aar 文件夾。

如圖所示:

然后就可以添加依賴了,如下所示:

compile(name:'YibaAnalytics-release', ext:'aar')

6、依賴配置

有些時候,你可能需要和sdk協(xié)調(diào)工作。為了能順利編譯你的代碼,你需要添加SDK到你的編譯環(huán)境。你不需要將sdk包含在你的APK中,因?yàn)樗缫呀?jīng)存在于設(shè)備中,所以配置來啦,我們會有5個不同的配置:

  • compile
  • apk
  • provided
  • testCompile
  • androidTestCompile

compile是默認(rèn)的那個,其含義是包含所有的依賴包,即在APK里,compile的依賴會存在。

apk的意思是apk中存在,但是不會加入編譯中,這個貌似用的比較少。

provided的意思是提供編譯支持,但是不會寫入apk。

7、排除依賴兼容包

有時候我們在引入依賴包的時候,會額外的引入 v7, v4 的包,對我們的項(xiàng)目造成額外的負(fù)擔(dān),我們需要把這個兼容包排除,可以使用 exclude 就能做到。

compile('com.google.firebase:firebase-ads:11.0.4', {exclude group: 'com.android.support' //排除v7 , v4 包 })

native包(so包)

用c或者c++寫的library會被叫做so包,Android插件默認(rèn)情況下支持native包,你需要把.so文件放在對應(yīng)的文件夾中:

注意

jniLibs 目錄應(yīng)該和 Java 目錄在同一級

defaultConfig 詳解

defaultConfig 對應(yīng)的是 ProductFlavor 類。

resConfigs : 過濾語言

如果你的app中僅支持1,2種語言,但是可能引用的lib庫包含多種其他語言的strings資源,這個時候我們可以通過resConfig指定我們需要的strings資源。

android {defaultConfig {applicationId "com.yiba.sharewe.lite.activity"minSdkVersion 14targetSdkVersion 24versionCode 46versionName "1.74"resConfigs 'en', 'zh-rCN' ,'es' //本次打包,只把 en(英文)、zh-rCN(中文簡體)、es(西班牙語)打進(jìn)保內(nèi),其他語言忽略} }

resConfigs : 過濾 drawable文件夾的資源

一般情況下,我們打完包,res 下面的資源如圖所示:

現(xiàn)在加上資源過濾規(guī)則:

android {defaultConfig {applicationId "com.wifi.analytics"minSdkVersion 9targetSdkVersion 25versionCode 1versionName "1.0"resConfigs "hdpi" //打包的時候只保留 drawable-xhdpi 文件夾里面的資源}}

這次我們打包效果如下:

buildTypes 詳解

官方文檔

buildTypes{}對應(yīng)的是 BuildType 類

繼承關(guān)系

BuildType 繼承 DefaultBuildType ; DefaultBuildType 繼承 BaseConfigImpl ;

BaseConfigImpl--- DefaultBuildType --- BuildType

buildTypes的屬性:

name:build type的名字applicationIdSuffix:應(yīng)用id后綴versionNameSuffix:版本名稱后綴debuggable:是否生成一個debug的apkminifyEnabled:是否混淆proguardFiles:混淆文件signingConfig:簽名配置manifestPlaceholders:清單占位符shrinkResources:是否去除未利用的資源,默認(rèn)false,表示不去除。zipAlignEnable:是否使用zipalign工具壓縮。multiDexEnabled:是否拆成多個DexmultiDexKeepFile:指定文本文件編譯進(jìn)主Dex文件中multiDexKeepProguard:指定混淆文件編譯進(jìn)主Dex文件中

buildType的方法:

1.buildConfigField(type,name,value):添加一個變量生成BuildConfig類。2.consumeProguardFile(proguardFile):添加一個混淆文件進(jìn)arr包。3.consumeProguardFile(proguardFiles):添加混淆文件進(jìn)arr包。4.externalNativeBuild(action):配置本地的build選項(xiàng)。5.initWith:復(fù)制這個build類型的所有屬性。6.proguardFile(proguardFile):添加一個新的混淆配置文件。7.proguradFiles(files):添加新的混淆文件8.resValue(type,name,value):添加一個新的生成資源9.setProguardFiles(proguardFileIterable):設(shè)置一個混淆配置文件。

initWith :復(fù)制屬性

android {compileSdkVersion 25buildToolsVersion "25.0.2"defaultConfig {applicationId "com.wifi.analytics"minSdkVersion 9targetSdkVersion 25versionCode 1versionName "1.0"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}myType {initWith debug //完全復(fù)制 debug 的所有屬性‘minifyEnabled true //自定義打開混淆}} }

applicationIdSuffix 、versionNameSuffix :添加后綴

android {compileSdkVersion 25buildToolsVersion "25.0.2"defaultConfig {applicationId "com.wifi.analytics"minSdkVersion 9targetSdkVersion 25versionCode 1versionName "1.0"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'applicationIdSuffix "zhao" //applicationId 追加后綴名 zhaoversionNameSuffix "debug" //versionName 追加后綴名 debug1.0}}

效果圖,如下:

buildConfigField: 自定義屬性

在 build.gradle 文件中定義 buildConfigField 屬性

android {buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'buildConfigField "String", "API_ENV", "\"http://yiba.com\"" //自定義String屬性}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'buildConfigField "String", "API_ENV", "\"http://yiba.com\"" //自定義String屬性}} }

然后點(diǎn)擊同步按鈕,然后就可以在 build 目錄看到 debug 和 release 信息。

debug 環(huán)境下的 BuildConfig 如下:

release 環(huán)境下的 BuildConfig 如下:

當(dāng)然我們也可以在代碼中獲取自定義的值:

//獲取變量值 String API = BuildConfig.API_ENV ;

上面演示了自定義 String 變量,也可以 自定義 int 、boolean

android {buildTypes {debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'buildConfigField "String", "API_ENV", "\"http://www.baidu.com\"" //自定義 String 值buildConfigField "Boolean", "openLog", "true" //自定義 boolean 值buildConfigField "int", "age", "10" //自定義 int 值}} }

Gradle 實(shí)現(xiàn)差異化構(gòu)建

情景1

LeakCanary 是 square 公司出品的一個檢測內(nèi)存泄漏的開源庫。

GitHub : https://github.com/square/leakcanary

我們一般這樣集成

dependencies {compile 'com.squareup.leakcanary:leakcanary-android:1.5.2' }

然后我們在 Application 類中初始化:

public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();LeakCanary.install(this);} }

但是這樣集成有一個弊端,就是 debug 和 release 包都會把 LeakCanary 的源碼打進(jìn)去,如果我們在 release 包中不把 LeakCanary 源碼打進(jìn)去,怎么辦? 還好 LeakCanary 給我們提供了一個方法,方法如下:

dependencies {//打 debug 包debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'//打 release 包releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'}

leakcanary-android-no-op 是一個空殼,里面有2個空類,所以就可以避免把 LeakCanary 源碼打進(jìn) release 包。但是這種方式有個缺陷,如果一些開源庫沒有提供 releaseCompile 庫,那我們改怎么辦了?下面的情景2 就會講到解決方案。

情景2

Stetho 是 Faceboo k開源的Andorid調(diào)試工具。當(dāng)你的應(yīng)用集成Stetho時,開發(fā)者可以訪問Chrome,在Chrome Developer Tools中查看應(yīng)用布局,網(wǎng)絡(luò)請求,sqlite,preference 等等。

官網(wǎng):http://facebook.github.io/stetho/

從官網(wǎng)可以看到 stetho 沒有提供 releaseCompile 包 , 情景1 的方案就不能用了。新的思路集成方案如下:

dependencies {debugCompile 'com.facebook.stetho:stetho:1.5.0' }

在 src 目錄下創(chuàng)建 debug 目錄、release 目錄 ,然后分別在 debug 目錄 和 release 目錄 創(chuàng)建 java 目錄 , 在 java 目錄中創(chuàng)建包名,比如: com.app , 如下圖所示:

debug 目錄下創(chuàng)建 SDKManage 類 ,如下 :

public class SDKManager {public static void init(Context context) {//初始化 StethoStetho.initializeWithDefaults(context);} }

release 目錄下創(chuàng)建 SDKManage 類 ,如下 :

public class SDKManager {public static void init(Context context) { //這是一個空方法,目的是不引入 Stetho 源碼}}

在住項(xiàng)目中的 MyApplication 類,并且完成 Stetho 的初始化,如下:

public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();SDKManager.init(this);} }

這樣我們便完成了簡單的差異化構(gòu)建, 打出來的 release 包就沒有 Stetho 源碼。

SourceSet

SourceSet 簡介

SourceSet 可以定義項(xiàng)目結(jié)構(gòu),也可以修改項(xiàng)目結(jié)構(gòu)。Java插件默認(rèn)實(shí)現(xiàn)了兩個SourceSet,main 和 test。每個 SourceSet 都提供了一系列的屬性,通過這些屬性,可以定義該 SourceSet 所包含的源文件。比如,java.srcDirs,resources.srcDirs 。Java 插件中定義的其他任務(wù),就根據(jù) main 和 test 的這兩個 SourceSet 的定義來尋找產(chǎn)品代碼和測試代碼等。

SourceSet 定義源碼目錄

在 Android 項(xiàng)目中,我們可以在 src/main/java 目錄新建 Java 文件,如下圖所示:

現(xiàn)在我們在 src 目錄下,新建 test1 目錄 ,發(fā)現(xiàn)不能在 test1 目錄中新建 Java 文件,如下圖所示:

為什么在 test1 目錄不能新建 Java 文件,因?yàn)?Gradle 中 SourceSet 默認(rèn)定義的源碼文件路徑是src/main/java , 其他的文件下下面的源碼我們自然無法訪問。解決這個問題也很簡單,我們需要在 SourceSet 中增加一個源碼路徑即可。如下所示:

android {sourceSets {main {java {srcDir 'src/test1' //指定源碼目錄}}} }

然后同步一下,就可以在 test1 目錄中新建 Java 文件了。如下圖所示:

當(dāng)然我們也可以同時指定多個源碼目錄,比如同時指定 test1 , test2 , test3 為源碼目錄。

android {sourceSets {main {java {srcDir 'src/test1' //指定 test1 為源碼目錄srcDir 'src/test2' //指定 test2 為源碼目錄srcDir 'src/test3' //指定 test3 為源碼目錄}}} }

或者 這樣寫 :

android {sourceSets {main {java.srcDirs( 'src/test1' , 'src/test2' ,'src/test3' )}} }

效果如下圖所示:

SourceSet 定義資源目錄

定義 test1 目錄 Java 源代碼路徑、res 資源目錄。目錄結(jié)構(gòu)如下圖所示:

android {sourceSets {main {java.srcDirs('src/test1/java') //定義java 源代碼res.srcDirs('src/test1/res') //定義資源目錄(layout , drawable,values)}} }

SourceSet 實(shí)現(xiàn) layout 分包

對于一個大項(xiàng)目來說,頁面太多,布局文件就很多,有時在眾多布局文件中找某個模塊的布局文件,很是痛苦,為了解決這個問題,我們可以在創(chuàng)建多個 layout 目錄,不同模塊的布局文件放在不同的 layout 目錄中,這樣查找起來,就容易很多。

例子:

比如我們的項(xiàng)目中,有兩個模塊分別為:登錄、注冊。

  • 第一步:把項(xiàng)目中 layout 文件夾改名字為 layouts

  • 第二步:在 layouts 目錄下,分別創(chuàng)建 login 、register 目錄 。

  • 第三步:分別在 login 、register 目錄下創(chuàng)建 layout 目錄。注意這一步是必須的,否則會報錯。

  • 第四步:把 登錄布局文件、注冊布局文件 分別放在 第三步創(chuàng)建的對應(yīng)的 layout 目錄下。

效果圖如下:

SourceSet 實(shí)現(xiàn)如下:

android {sourceSets {main {res.srcDirs 'src/main/res/layouts/login' //定義登錄布局目錄res.srcDirs 'src/main/res/layouts/register' //定義注冊布局目錄}} }

SourceSet 定義 AndroidManifest 文件

指定 test1 目錄下的 AndroidManifest 文件。項(xiàng)目結(jié)構(gòu)如下圖所示:

代碼如下:

android {sourceSets {main {manifest.srcFile 'src/test1/AndroidManifest.xml'}} }

在組件化開發(fā)中, 我們需要針對 debug 與 release 模式下, 指定不同的 Manifest 文件, 代碼如下:

android {def appDebug = false;buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'appDebug = false;}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'appDebug = false;}}sourceSets {main {if (appDebug) {manifest.srcFile 'src/test1/AndroidManifest.xml'} else {manifest.srcFile 'src/main/AndroidManifest.xml'}}} }

SourceSet 定義 assets 目錄

Android Studio 項(xiàng)目目錄中,assets 默認(rèn)目錄如下:

如何重新定義 assets 目錄 。在項(xiàng)目的根目錄下創(chuàng)建 assets 目錄,如下圖所示:

sourceSets 定義代碼如下:

android {sourceSets {main {assets.srcDirs = ['assets']}} }

SourceSet 定義其他資源

android {sourceSets {main {jniLibs.srcDirs //定義 jni 目錄aidl.srcDirs //定義 aidl 目錄}} }

applicationVariants

定義 versionName 、VersionCode

在打包的時候分 debug 、release 版本 , 需要控制 versionName

android {applicationVariants.all { variant ->def flavor = variant.mergedFlavordef versionName = flavor.versionNameif (variant.buildType.isDebuggable()) {versionName += "_debug" //debug 名字} else {versionName += "_release" //release 名字}flavor.versionName = versionName}}

定義 APK 包的名字

apply plugin: 'com.android.application'android {defaultConfig {applicationId "android.plugin"minSdkVersion 14targetSdkVersion 25versionCode 1versionName "1.0"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}//定義渠道productFlavors {xiaomi {//小米}wandoujia {// 豌豆莢}}//打包命名applicationVariants.all {variant ->variant.outputs.each {output ->//定義一個新的apk 名字。// 新名字 = app 名字+ 渠道號 + 構(gòu)建類型 + 版本號 + 當(dāng)前構(gòu)建時間def apkName = "appName_${variant.flavorName}_${buildType.name}_v${variant.versionName}_${getTime()}.apk";output.outputFile = new File(output.outputFile.parent, apkName);}}}//獲取當(dāng)前時間 def getTime() {String today = new Date().format('YY年MM月dd日HH時mm分')return today }

效果圖如下:

Task

定義 task

//定義任務(wù)1 task task1<<{println 'task1' }//定義任務(wù)2 task task2<<{println 'task2' }

mustRunAfter 定義 task 執(zhí)行順序

//task2 的執(zhí)行順訊在 task1 之后 task2.mustRunAfter task1
  • 測試1 : gradlew task1

效果如下:

:app:task1 task1
  • 測試2 : gradlew task2

效果如下:

:app:task2 task2
  • 測試3 : gradlew task1 task2

效果如下:

:app:task1 task1 :app:task2 task2
  • 測試4 : gradlew task2 task1

效果如下:

:app:task1 task1 :app:task2 task2

結(jié)論

如果單獨(dú)執(zhí)行 task1 就只會執(zhí)行 task1 的任務(wù);單獨(dú)執(zhí)行 task2 就只會執(zhí)行 task2 的任務(wù);
如果同時執(zhí)行 task1、task2 , 一定會先執(zhí)行 task1 , 等 task1 執(zhí)行完后,就會執(zhí)行 task2 內(nèi)容。

擴(kuò)展

上面 mustRunAfter 我們還有一種寫法,如下圖所示:

task2 {}.mustRunAfter task1

這個寫法的效果和 mustRunAfter 是一樣的,當(dāng)然我們還可以在 花括號里面寫一些任務(wù),比如 :

task2 {println '我最先執(zhí)行' }.mustRunAfter task1

下面做個測試,測試命令如下:

gradlew task2 task1

效果如下:

我最先執(zhí)行:app:task1 task1 :app:task2 task2

dependsOn 定義 task 依賴

task2 任務(wù)依賴于 task1 ,執(zhí)行 task2 就會先執(zhí)行 task1

task2.dependsOn task1

測試:

gradlew task2

效果如下:

:app:task1 task1 :app:task2 task2

常用 Gradlew 命令

  • 1、gradlew -v : 查看版本號
------------------------------------------------------------ Gradle 3.3 ------------------------------------------------------------Build time: 2017-01-03 15:31:04 UTC Revision: 075893a3d0798c0c1f322899b41ceca82e4e134bGroovy: 2.4.7 Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 JVM: 1.8.0_112 (Oracle Corporation 25.112-b15) OS: Windows 10 10.0 amd64
  • 2、gradlew task : 查看所有的 task

Gradle 日志管理

Log 等級

除了常用的 debug , info , warning , error ,gradle 自己特有的 quiet 和l ifecycle 。

級別用途
ERROR錯誤信息
QUIET重要信息
WARNING警告信息
LIFECYCLE警告信息
INFO警告信息
DEBUG調(diào)試信息
  • 小例子

build.gradle

task hello << {logger.quiet("重要信息")logger.info("信息")logger.debug("調(diào)試信息")logger.lifecycle("過程信息")//自定義信息等級logger.log(LogLevel.ERROR, "錯誤信息")}

改變默認(rèn)輸出

println 后跟信息,gradle 會將其重定向到日志系統(tǒng)中,默認(rèn)為 quiet 等級。

當(dāng)然你可以使用logger屬性來編寫不同等級的。

  • 舉個栗子

build.gradle

task hello <<{println( "我是一條普通的輸出")//改變默認(rèn)的標(biāo)準(zhǔn)輸出為error級別logging.captureStandardOutput(LogLevel.ERROR)println( "我是一條不普通的輸出") }

效果如下:

參考資料

Android 利用Gradle實(shí)現(xiàn)差異化構(gòu)建

楊海 Android目錄結(jié)構(gòu)


個人微信號:zhaoyanjun125 , 歡迎關(guān)注
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-YbAN8mrk-1604564656923)(http://o7rvuansr.bkt.clouddn.com/weixin200.jpg)]

總結(jié)

以上是生活随笔為你收集整理的Android Gradle使用总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。