欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

你該知道的Gradle配置知識(shí)總結(jié)

 更新時(shí)間:2017年10月12日 10:37:58   作者:BeWinner  
這篇文章主要給大家介紹了關(guān)于Gradle配置的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考學(xué)習(xí),下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。

前言

本文主要介紹了關(guān)于Gradle配置的相關(guān)知識(shí),分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。

參考鏈接:https://developer.android.com/studio/build/index.html

本片文章的內(nèi)容全部參考自上面的鏈接,其中有些內(nèi)容是直接翻譯的,有些內(nèi)容是結(jié)合自己的經(jīng)驗(yàn)總結(jié)的,可能有理解錯(cuò)誤的地方,非常希望大家能指正出來(lái),在交流中進(jìn)步。

Gradle 編譯過(guò)程


編譯流程圖

上圖展示了一個(gè)典型的 App 編譯過(guò)程,主要分為以幾步:

  • 編譯器將源代碼(包括依賴(lài)庫(kù))轉(zhuǎn)化為 DEX 文件,編譯資源文件(res 以及 assets 文件下的資源)。
  • APK Packager 整合所有的 DEX 文件和編譯過(guò)的資源文件,并且對(duì) APK 進(jìn)行簽名。
  • 簽名文件必須使用 Debug 版或者 Release 版,使用 Debug Keystore 生成的 app 被用來(lái)測(cè)試和分析,使用 Release Keystore 生成的 app 可以進(jìn)行發(fā)布供其他用戶(hù)使用。
  • 在生成最終的 APK 之前,APK Packager 會(huì)使用 zipalign 工具優(yōu)化整個(gè) app ,以便 app 在使用的過(guò)程中更加節(jié)省內(nèi)存。

自定義編譯配置

Android Studio 的 gradle 插件方便我們?cè)谝韵聨讉€(gè)方面配置我們的編譯選項(xiàng):

Build Types - 編譯類(lèi)型

編譯類(lèi)型,包括我們最熟悉的 release 和 debug 兩種類(lèi)型,我們可以根據(jù)這兩種類(lèi)型定義出更多的類(lèi)型。配置對(duì)應(yīng)的 build.gradle 文件在 moudle 下,需要添加新的或者修改 Build Type ,只需要在 android{ ... }里面操作。

一個(gè)示例如下:

android {
 ...
 defaultConfig {...}
 buildTypes {
 release {
  //開(kāi)啟混淆
  minifyEnabled true
  //混淆規(guī)則文件
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }

 debug {
  //apk的后綴
  applicationIdSuffix ".debug"
 }

 //debug的一個(gè)擴(kuò)展
 jnidebug {
  // 復(fù)制debug的屬性和簽名配置
  initWith debug
  applicationIdSuffix ".jnidebug"
  //開(kāi)啟Jni調(diào)試
  jniDebuggable true
 }
 }
}

其中 initWith 可以方便我們繼承其他的配置,只需要添加需要的部分。

Product Flavors - 構(gòu)建不同版本

配置 apk 的版本信息,可以為每一個(gè)版本指定不同的 applicationId 和版本名稱(chēng)。關(guān)于 applicationId ,可以把它也理解為包名,不過(guò)和 Manifest 文件中的包名作用不同,它是用來(lái)給應(yīng)用商店和設(shè)備區(qū)分不同的 app ,而 Manifest 中的 pakage 屬性用來(lái)在源代碼中引用 R 類(lèi)和其他類(lèi)。即同一份代碼 applicationId 可以讓它變成不同的 app 。

示例配置如下:

android {
 ...
 defaultConfig {...}
 buildTypes {...}
 productFlavors {
 demo {
  applicationId "com.example.myapp.demo"
  versionName "1.0-demo"
 }
 full {
  applicationId "com.example.myapp.full"
  versionName "1.0-full"
 }
 }
}

通過(guò)上面的配置之后,如果 buildTypes 里面配置了兩個(gè)編譯類(lèi)型,假如是 debug 和 release ,將會(huì)產(chǎn)生四個(gè) apk 文件,每一種 buildType 都會(huì)和每種 flavor 進(jìn)行組合拼接,進(jìn)而產(chǎn)生不同的變種版本(Build Variant),上面對(duì)應(yīng)的四個(gè)不同的變種版本分別是:demoDebug、demoRelease、fullDebug、fullRelease。

Mutiple Manifest Files - 合并多個(gè)清單文件

配置多個(gè) Manifest 文件。經(jīng)常會(huì)在項(xiàng)目中依賴(lài)其他項(xiàng)目,這個(gè)時(shí)候就會(huì)有多個(gè) Manifest 文件,那在編譯的時(shí)候該如何處理呢?這個(gè)時(shí)候需要進(jìn)行合并,而且還必須有一套相應(yīng)的合并規(guī)則解決和避免合并沖突。對(duì)于不同的 Manifest 文件中同一個(gè)屬性的不同值,在合并的時(shí)候還需要優(yōu)先級(jí)來(lái)進(jìn)行判斷,用高優(yōu)先級(jí)的去覆蓋低優(yōu)先級(jí)的。

關(guān)于優(yōu)先級(jí)定義如下:

  • 最高優(yōu)先級(jí):buildType 的設(shè)置
  • 次高優(yōu)先級(jí):productFlavor 的設(shè)置
  • 中等優(yōu)先級(jí):在 src/main 目錄下的 Manifest 文件
  • 最低優(yōu)先級(jí):各種依賴(lài)和第三方庫(kù)的設(shè)置

合并規(guī)則:概括來(lái)說(shuō)是這樣:

  • 合并之前,先將每個(gè) module 里面的 buildType 內(nèi)容寫(xiě)到 Manifest 里面去,比如你在 buildType 里面的 minSdkVersion 和targetSdkVersion 以及 versionCode 和 VersionName 等等(此時(shí)合并后的 Manifest 文件可以在 app/intermediates/manifests/* 目錄下查看)。
  • 對(duì)于同一個(gè)屬性,當(dāng)高優(yōu)先級(jí)和低優(yōu)先級(jí)都為非默認(rèn)值時(shí),如果可以匹配,那直接合并,不能匹配,就會(huì)產(chǎn)生沖突(這種是針對(duì)兩個(gè)不同的 module 來(lái)說(shuō)),下面會(huì)專(zhuān)門(mén)給出例子。
  • 不管高優(yōu)先級(jí)還是低優(yōu)先級(jí),如果其中一個(gè)沒(méi)有設(shè)置該屬性或者設(shè)置為默認(rèn)的屬性值,而另外一個(gè)設(shè)置了非默認(rèn)的屬性值,則合并的結(jié)果就是非默認(rèn)的屬性值,在項(xiàng)目編譯后,可以查看 Manifest 的合并記錄,該文件目錄為:app/intermediates/outputs/logs/manifest*.txt。

示例:現(xiàn)在給出一些例子說(shuō)明上述規(guī)則,我的主 module 名為 app ,新建一個(gè)依賴(lài)的 module 叫 uisdk ,現(xiàn)在分別給出兩個(gè) module 的 build.gradle 文件:

app/build.gradle

apply plugin: 'com.android.application'

android {
 compileSdkVersion 24
 buildToolsVersion "24.0.0"

 defaultConfig {
 applicationId "com.example.rth.study"
 minSdkVersion 15
 targetSdkVersion 24
 versionCode 1
 versionName "1.0"
 }
 buildTypes {
 release {
  minifyEnabled false
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }
 productFlavors {
 demo {
  minSdkVersion 7
  applicationId "com.rth.app"
 }
 }
}

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

uisdk/build.gradle

apply plugin: 'com.android.library'

android {
 compileSdkVersion 24
 buildToolsVersion "24.0.0"

 defaultConfig {
 minSdkVersion 8
 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.0.0'
}

在 app/build.gradle 里面,defaultConfig 的 minSdkVersion 為15,但我在變種版本(productFlavors 里的 demo)里設(shè)置的 minSdkVersion 為7,最終 app 的 Manifest 的 minSdkVersion 就為7,再看 uisdk 里面的 build.gradle ,minSdkVersion 為8,就是說(shuō) app 這個(gè) module 和 uisdk 這個(gè) module library 在同一個(gè)屬性上使用了不同的非默認(rèn)值,而且 library 的 Manifest 屬于最低優(yōu)先級(jí),它設(shè)置的值又比優(yōu)先級(jí)比它高的值還要高,就會(huì)出錯(cuò),出錯(cuò)信息的描述也很清晰:

Error:Execution failed for task ':app:processDemoDebugManifest'.
Manifest merger failed : uses-sdk:minSdkVersion 7 cannot be smaller than version 8 declared in library 
...
Suggestion: use tools:overrideLibrary="com.example.uisdk" to force usage

根據(jù)錯(cuò)誤信息,我們有兩種方式解決這個(gè)問(wèn)題:

  • 把 app 里面的值調(diào)高,或者把 uisdk 里面的值調(diào)低。
  • 就像上面建議的那樣,使用 overrideLibrary 這個(gè)標(biāo)簽。該標(biāo)簽的作用在名字上已經(jīng)體現(xiàn)出來(lái)了,就是直接覆蓋 library 里面的設(shè)置,現(xiàn)在我們?cè)?app/src/main/Manifest 里面加上這么一句:
<uses-sdk tools:overrideLibrary="com.example.uisdk"/>

就能編譯通過(guò)了,這適用于比較特殊的情況,就是在依賴(lài)庫(kù)里可能要適用一些新特性,這些特性在 app 的 minSdkVersion 下不能使用,而且 app 的 minSdkVersion 已經(jīng)不能更改了。

標(biāo)記選擇器(Marker Selectors) :選擇器的功能可以讓一些屬性在某些 libary 里面無(wú)效,比如就拿上面的例子來(lái)說(shuō),我想讓 uisdk 只處理 ui 上的東西,不想讓他具有網(wǎng)絡(luò)訪問(wèn)的功能,那么我可以這么設(shè)置:

<uses-permission android:name="android.permission.INTERNET"
 tools:node="remove"
 tools:selector="com.example.uisdk"
 />

其中 tools:node 標(biāo)簽表示刪除該權(quán)限,tools:selector 標(biāo)簽選擇在哪個(gè)依賴(lài)庫(kù)里執(zhí)行 tools:node 表示的動(dòng)作。

可以看出這些配置還是挺靈活的。

Configure dependencies - 配置依賴(lài)

這個(gè)應(yīng)該是最熟悉的了,項(xiàng)目中經(jīng)常要依賴(lài)第三方庫(kù),一個(gè)典型了例子如下:

android {...}
...
dependencies {
 //將本地 module library 編譯到項(xiàng)目中
 compile project(":mylibrary")
 //編譯遠(yuǎn)程依賴(lài)
 compile 'com.android.support:appcompat-v7:23.4.0'
 //編譯本地 jar 包
 compile fileTree(dir: 'libs', include: ['*.jar'])
}

上面主要用到的方式是 compile ,gradle 支持6種編譯方式:

  • compile:對(duì)所有 buildType 以及 flavors 進(jìn)行編譯并打包到 apk 。
  • provided:和 compile 相似,但只在編譯時(shí)使用,幾只參與編譯,不打包到最終 apk 。
  • apk:只會(huì)打包到 apk 中,不參與編譯,所以不能在項(xiàng)目代碼中使用相應(yīng)庫(kù)中的方法。
  • test compile:相比于 compile ,僅僅針對(duì)單元測(cè)試的代碼編譯打包。
  • debug compile:僅針對(duì) debug 模式編譯打包。
  • release compile:僅針對(duì) release 模式編譯打包。

另外在進(jìn)行 sdk 開(kāi)發(fā)時(shí),一般為了減小 sdk 體積,一些依賴(lài)庫(kù)會(huì)用 provided 的方式,同時(shí)需要注意的是,對(duì)于遠(yuǎn)程依賴(lài),compile 和 provided 的效果一樣,都不會(huì)打包到 jar 包或者 arr 包中,但對(duì)于本地的 jar 包或者 arr 包的依賴(lài),compile 和 provided 就有區(qū)別了。

Configure Sigining - 配置簽名

在用 gradle 配置 release 版本的簽名信息時(shí),需要下面三個(gè)步驟:

  • 生成一個(gè) keystore ,一個(gè)二進(jìn)制文件保存一些私鑰,這個(gè)必須好好保存。
  • 生成一個(gè)私鑰,用于開(kāi)發(fā)者或者公司與這個(gè) app 建立對(duì)應(yīng)關(guān)系。
  • 將生成的信息配置到 moudle 層的 build.gradle 里。

示例如下:

android {
...
defaultConfig {...}
signingConfigs {
 release {
  storeFile file("myreleasekey.keystore")
  storePassword "password"
  keyAlias "MyReleaseKey"
  keyPassword "password"
 }
}
buildTypes {
 release {
  ...
  signingConfig signingConfigs.release
 }
}
}

上面的配置中直接顯示了一些敏感信息,比如各種密碼,一種更加安全的方式是通過(guò)環(huán)境變量的方式獲取:

storePassword System.getenv("KSTOREWD");
keyPassword System.getenv("KEYPWD");

或者如果使用命令行的方式編譯,還可以讓用戶(hù)在命令行輸入密碼:

storePassword System.console().readLine("\nKeystore password: ")
keyPassword System.console().readLine("\nKey password: ")

暫時(shí)就總結(jié)到這么多了,再次說(shuō)明,如果發(fā)現(xiàn)理解錯(cuò)的地方歡迎指正?。。?/p>

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

最新評(píng)論