前言
本文主要介紹了關于Gradle配置的相關知識,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。
參考鏈接:https://developer.android.com/studio/build/index.html
本片文章的內容全部參考自上面的鏈接,其中有些內容是直接翻譯的,有些內容是結合自己的經驗總結的,可能有理解錯誤的地方,非常希望大家能指正出來,在交流中進步。
Gradle 編譯過程
	
	編譯流程圖
上圖展示了一個典型的 App 編譯過程,主要分為以幾步:
自定義編譯配置
Android Studio 的 gradle 插件方便我們在以下幾個方面配置我們的編譯選項:
Build Types - 編譯類型
編譯類型,包括我們最熟悉的 release 和 debug 兩種類型,我們可以根據這兩種類型定義出更多的類型。配置對應的 build.gradle 文件在 moudle 下,需要添加新的或者修改 Build Type ,只需要在 android{ ... }里面操作。
一個示例如下:
android { ... defaultConfig {...} buildTypes { release {  //開啟混淆  minifyEnabled true  //混淆規則文件  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug {  //apk的后綴  applicationIdSuffix ".debug" } //debug的一個擴展 jnidebug {  // 復制debug的屬性和簽名配置  initWith debug  applicationIdSuffix ".jnidebug"  //開啟Jni調試  jniDebuggable true } }}其中 initWith 可以方便我們繼承其他的配置,只需要添加需要的部分。
Product Flavors - 構建不同版本
配置 apk 的版本信息,可以為每一個版本指定不同的 applicationId 和版本名稱。關于 applicationId ,可以把它也理解為包名,不過和 Manifest 文件中的包名作用不同,它是用來給應用商店和設備區分不同的 app ,而 Manifest 中的 pakage 屬性用來在源代碼中引用 R 類和其他類。即同一份代碼 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" } }}通過上面的配置之后,如果 buildTypes 里面配置了兩個編譯類型,假如是 debug 和 release ,將會產生四個 apk 文件,每一種 buildType 都會和每種 flavor 進行組合拼接,進而產生不同的變種版本(Build Variant),上面對應的四個不同的變種版本分別是:demoDebug、demoRelease、fullDebug、fullRelease。
Mutiple Manifest Files - 合并多個清單文件
配置多個 Manifest 文件。經常會在項目中依賴其他項目,這個時候就會有多個 Manifest 文件,那在編譯的時候該如何處理呢?這個時候需要進行合并,而且還必須有一套相應的合并規則解決和避免合并沖突。對于不同的 Manifest 文件中同一個屬性的不同值,在合并的時候還需要優先級來進行判斷,用高優先級的去覆蓋低優先級的。
關于優先級定義如下:
合并規則:概括來說是這樣:
示例:現在給出一些例子說明上述規則,我的主 module 名為 app ,新建一個依賴的 module 叫 uisdk ,現在分別給出兩個 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)里設置的 minSdkVersion 為7,最終 app 的 Manifest 的 minSdkVersion 就為7,再看 uisdk 里面的 build.gradle ,minSdkVersion 為8,就是說 app 這個 module 和 uisdk 這個 module library 在同一個屬性上使用了不同的非默認值,而且 library 的 Manifest 屬于最低優先級,它設置的值又比優先級比它高的值還要高,就會出錯,出錯信息的描述也很清晰:
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
根據錯誤信息,我們有兩種方式解決這個問題:
<uses-sdk tools:overrideLibrary="com.example.uisdk"/>
就能編譯通過了,這適用于比較特殊的情況,就是在依賴庫里可能要適用一些新特性,這些特性在 app 的 minSdkVersion 下不能使用,而且 app 的 minSdkVersion 已經不能更改了。
標記選擇器(Marker Selectors) :選擇器的功能可以讓一些屬性在某些 libary 里面無效,比如就拿上面的例子來說,我想讓 uisdk 只處理 ui 上的東西,不想讓他具有網絡訪問的功能,那么我可以這么設置:
<uses-permission android:name="android.permission.INTERNET" tools:node="remove" tools:selector="com.example.uisdk" />
其中 tools:node 標簽表示刪除該權限,tools:selector 標簽選擇在哪個依賴庫里執行 tools:node 表示的動作。
可以看出這些配置還是挺靈活的。
Configure dependencies - 配置依賴
這個應該是最熟悉的了,項目中經常要依賴第三方庫,一個典型了例子如下:
android {...}...dependencies { //將本地 module library 編譯到項目中 compile project(":mylibrary") //編譯遠程依賴 compile 'com.android.support:appcompat-v7:23.4.0' //編譯本地 jar 包 compile fileTree(dir: 'libs', include: ['*.jar'])}上面主要用到的方式是 compile ,gradle 支持6種編譯方式:
另外在進行 sdk 開發時,一般為了減小 sdk 體積,一些依賴庫會用 provided 的方式,同時需要注意的是,對于遠程依賴,compile 和 provided 的效果一樣,都不會打包到 jar 包或者 arr 包中,但對于本地的 jar 包或者 arr 包的依賴,compile 和 provided 就有區別了。
Configure Sigining - 配置簽名
在用 gradle 配置 release 版本的簽名信息時,需要下面三個步驟:
示例如下:
android {...defaultConfig {...}signingConfigs { release {  storeFile file("myreleasekey.keystore")  storePassword "password"  keyAlias "MyReleaseKey"  keyPassword "password" }}buildTypes { release {  ...  signingConfig signingConfigs.release }}}上面的配置中直接顯示了一些敏感信息,比如各種密碼,一種更加安全的方式是通過環境變量的方式獲?。?/p>
storePassword System.getenv("KSTOREWD");keyPassword System.getenv("KEYPWD");或者如果使用命令行的方式編譯,還可以讓用戶在命令行輸入密碼:
storePassword System.console().readLine("/nKeystore password: ")keyPassword System.console().readLine("/nKey password: ")暫時就總結到這么多了,再次說明,如果發現理解錯的地方歡迎指正!??!
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。
新聞熱點
疑難解答