1. 程式人生 > >詳細配置android studio中的gradle

詳細配置android studio中的gradle

這篇部落格著重點在詳細的介紹如何配置gradle,實現諸如多渠道打包,一次生成不同UI的多渠道apk,自定義資源目錄等。如果你對gradle還沒有比較清晰的認識,那麼推薦你在看這篇部落格之前,先看下我的另一篇部落格理解與配置android studio的gradle,這篇部落格主要讓你認識gradle。

1.打包多渠道apk

使用gradle進行多渠道打包是對gradle的一個簡單的使用,gradle的功能非常強大,它還有很多值得深究的東西。目前,網路上已經有了大量關於多渠道打包的的資料可供參考,這裡不做深究,主要展示一下多渠道打包的流程,如果你想深究,那麼,認真看完這篇部落格的第三章,你不禁能對多渠道打包有個較好的理解,還能使用gradle做更多很酷的事。

 1.1修改AndroidManifest

渠道資訊在AndroidManifest中一般使用如下方式標示:
<meta-data
    android:name="UMENG_CHANNEL"
    android:value="${UMENG_CHANNEL_VALUE}" />

這裡面的value是個可變的值,它之所以可變,是因為在build.gradle中的productFlavors 這個script block下給每個渠道商下的UNMENG_CHANNEL_VALUE賦了不同的值。

 1.2修改module下的build.gradle

<span style="font-size:14px;">productFlavors {
    wandoujia {}
    baidu {}
    productFlavors.all {
        flavor->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
}</span>

這段程式碼中,productFlavors是一個方法,{...}是一個閉包,閉包中自定義了兩個方法,這兩個方法的引數又都是閉包。android dsl使用了很多簡寫,比如baidu函式的定義,你可以這樣寫:baidu({...})這樣看著就像是一個定義了一個方法,它的引數是一個closrue(閉包)。productFlavors的引數---閉包裡面的productFlavors和是一個物件,她和它外面長得一樣的那位沒什麼直接關係,這個物件有個方法叫all,呼叫它,然後又傳入一個閉包。如果這裡不明白,可以看一下我在文章開頭推薦的那篇部落格。它裡面對android dsl有詳細的介紹。總之這裡就是給UMENG_CHANNEL_VALUE賦不同的值。

 1.3生成apk

最好安裝好gradle工具,配置好環境變數,然後在cmd或者android studio的控制檯中輸入以下命名:
gradle assemble ,assemble是個task,此外,還有assembleRelease,assembleDebug兩個task可用,它們的作用分別是全部編譯、
只編譯release版和只編譯debug版。

gradle assemble 執行後生成的apk:

gradle assembleRelease執行後生成的apk:


2. sourceSets,資源路徑配置

sourceSets是build.gradle中的一個script block,它的功能主要是配置工程下各個資源的路徑資訊,它可以像下面這樣:
<span style="font-size:14px;">    sourceSets {
        main {

        }
    }</span>
這裡展示了一個空的sourceSets,它任然可以很好地工作,因為它對每一項屬性都有一個預設值。如果使用預設的值的話,在build.gradle中是沒有必要再配置一遍的。為了讓自己的工程更加有特色一點,你可以修改他們中的任何一項。

2.1manifest

明確指定工程所用的manifest檔案雖然並不常用,但它可以做到:
<span style="font-size:14px;"> sourceSets {
        main {
            manifest.srcFile('MineManifest.xml')
        }
    }</span>
我原以為做了以上修改不會有問題,但事實上出現了錯誤:
<span style="font-size:14px;">Error:A problem was found with the configuration of task ':app:checkDebugManifest'.
> File 'E:\android\androidwork2.0\GradleTest2\app\MineManifest.xml' specified for property 'manifest' does not exist.</span>

說是找不到manifest,很鬱悶,不知道怎麼回事。我猜測可能是找不到MineManifest.xml檔案,這個檔案是我把AndroidManifest.xml改了個名字,那找不到怎麼辦呢?我嘗試加上絕對路勁試試,於是修改為如下程式碼:
<span style="font-size:14px;">    sourceSets {
        main {
            manifest.srcFile('/src/main/MineManifest.xml')
        }
    }</span>

是的,這樣就沒問題了。具體為什麼這麼匪夷所思,我搞不懂,如果你也碰到了這樣的問題,可以嘗試下加上絕對路勁。

2.2java,res,aidl等

這些資源路勁也是可以修改的:

<span style="font-size:14px;">    sourceSets {
        main {
            manifest.srcFile('/src/main/MineManifest.xml')
            java.srcDir('java')
            res.srcDir('res')
            aidl.srcDir('java')
        }
    }</span>

你可以修改他們預設的值,比如把java改成hello,這沒有問題,但是如果你把res改成其他,比如改成haha,如下:
<span style="font-size:14px;">    sourceSets {
        main {
            manifest.srcFile('/src/main/MineManifest.xml')
            java.srcDir('hello')
            res.srcDir('haha')
            aidl.srcDir('hello')
        }
    }</span>

就會報一下類似錯誤:

<span style="font-size:14px;">Error:(13, 23) No resource found that matches the given name (at 'icon' with value '@mipmap/ic_launcher').</span>

應該還是資源找不到,加上絕對路徑試試?是的,就可以了,內部不知道是怎麼實現的,但加上絕對路勁確實可以解決這種問題。修改以後變成這樣:

<span style="font-size:14px;">        main {
            manifest.srcFile('/src/main/MineManifest.xml')
            java.srcDir('/src/main/helo')
            res.srcDir('/src/main/haha')
            aidl.srcDir('/src/main/hello')
        }</span>

這裡關於這些資源目錄的配置可能和你見到到不太一樣,你見到的可能是這樣的:
<span style="font-size:14px;">    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        instrumentTest.setRoot('tests')
    }</span>

這兩種寫法是等價的,java,srcDir,res.srcDir等都是函式呼叫,只不過寫法不太一樣。既然是函式呼叫,我更加喜歡前面那種寫法,它更好理解,後面的寫法比較抽象。

3.配置buildTypes(做到一次生成多個不同ui的apk)

一次生成過個渠道釋出的不同UI的apk,這看起來很酷。所以我覺得這一章節是全文最有意思的地方。

3.1建立build 變數

建立build變數是很有用的,比如說你有這樣的需求:debug版列印Log,release版不列印Log,怎麼實現呢?

可做如下修改:

<span style="font-size:14px;">    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("string","DEBUG","false")
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("string","DEBUG","true")
        }
    }</span>

這裡主要使用resValue這個函式建立了一個build變數,這個變數會被寫到在BuildConfig類中,如下程式碼所示:
<span style="font-size:14px;">public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
 </span>
所以在程式碼中使用的時候,只需要這樣:
<span style="font-size:14px;">        if(BuildConfig.DEBUG){
            Log.d("hello","debug");
        }</span>

這樣就實現了debug版本列印Log,而release版本不列印Log。

3.2自定義build type

android studio中預設的build type 有兩種:debug和release,想像3.1展示的那樣,如果這些預設的build type滿足不了專案的需求的時候,你可以自定一個build type,所有你需要做的就是新建一個type,想下面這樣:

<span style="font-size:14px;">staging {
applicationIdSuffix ".staging"
versionNameSuffix "-staging"
buildConfigField "String", "API_URL",
"\"http://staging.example.com/api\""
}</span>
把它新增到buildTypes { }中,新增好以後,你可以在android studio左下的build Variants選單下選擇對應的staing,然後就可以編譯出使用staging作為build type的apk,如圖:



圖中,Build Variant是可選則的,你點選它看一下就會明白一切。此外,你還可以使用命令生成apk:gradle assemblestaging

執行這條命令的前提是你的系統中已經安裝了gradle工具,我還是推薦你安裝一個gradle,通過敲命令你更容易理解gradle工作的過程。關於為什麼可以執行這條命令,這裡還想囉嗦一下,staging畢竟使我們自定義的,gradle怎麼會知道它存在呢?是的這就是自動建立task,gradle會根據配置檔案自動給你生成需要的task,你如你有一個staging的build type,gradle就會生成一個assemblestaging的task,如果同時,你有一個flavor叫做baidu,gradle還會給你生成一個assedblebaidu的task,同時你還可以組合他們,比如:assemblebaidustaging,這裡是不是開始領悟gradle的強大了?

此外,自定義build type時,你可以充分利用已有的版本,然後在它的基礎上做一些修改,就像下面這樣:

<span style="font-size:14px;">android {
buildTypes {
staging.initWith(buildTypes.debug)
staging {
applicationIdSuffix ".staging"
versionNameSuffix "-staging"
debuggable = false
}
}
}</span>

可以看到staging使用debug型別初始化自己,然後在此基礎上做了些定製。

3.3build type與 source set

當你建立一個build type時,gradle會為你生成一個source set,預設的,它的目錄和你build type的名字相同,但是它不會自動為你建立目錄,你需要自己建立目錄,你只需要在和main同級的目錄下建立和build type名字相同的目錄即可,這個目錄結構和你原來的那個目錄很相似,下圖是新增staging後的目錄結構示意圖:

gradle這種強大的功能為你打開了一個新的世界,這使得你為不同的構建型別新增不同的程式碼,新增不同的資源成為可能。

3.3.1資源的合併

資源的處理比較特殊,當你使用不同的source set時,Drawable和layout檔案將會完全的覆蓋main source set下的同名檔案,但是value下的檔案,比如string.xml就不是這樣的,gradle合併的是內容而不是檔案。一定要注意它合併的是內容,這很重要。比如,某個build type 的source set中有這樣的string.xml:

<span style="font-size:14px;"><resources>
<string name="app_name">TypesAndFlavors STAGING</string>
</resources></span>
main source set下的string.xml是這樣:

<span style="font-size:14px;"><resources>
<string name="app_name">TypesAndFlavors</string>
<string name="hello_world">Hello world!</string>
</resources></span>

那麼使用main source set下的string.xml合併build type下的string.xml的內容,合併結果是這樣的:

<span style="font-size:14px;"><resources>
<string name="app_name">TypesAndFlavors STAGING</string>
<string name="hello_world">Hello world!</string>
</resources></span>

3.3.2給build type新增類檔案

給build type新增類檔案時,要注意,這個過程是互斥的,就是說main source set下的java檔案不能很buile type下的source set下的java檔案相同,比如,如果staging 的source set和main source set下都有一個A.java,那麼會暴錯,gradle會認為你的一個類定義了兩次。

3.3.3manifest檔案的合併

manifest檔案的合併和string.xml檔案的合併類似,是檔案內容的合併。因此,build type中的manifest檔案不需要完全複製main下的manifest檔案,只需要寫出不同於main source set下的manifest的部分。

3.3.4再談productFlavors

除了一次性生成多個productFlavors,和build type 類似,productFlavors也能生成自己的source set目錄,這個目錄也需要你自己區建立,名字和productFlavors宣告的flavor名字相同即可。更進一步,這個目錄和buile type的目錄名字可以組合使用。比如,我在productFlovors下定義了一個名為baidu的flavor,定義了一個staging的build type,然後目錄名就可以為baidustaging。

3.3.5一個實現生成多apk,不同UI,的工程例項

第一步:定義build type 和 product flavors 以及他們的sourceSets

這我們已經做過了,現在 直接把build.gradle貼出來:

<span style="font-size:14px;">apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.konka.gradletest2"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("string","DEBUG","false")
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            resValue("string","DEBUG","true")
            dependencies {

            }
        }
        staging {
            applicationIdSuffix ".staging"
            versionNameSuffix "-staging"
            buildConfigField "String", "API_URL",
                    "\"http://staging.example.com/api\""
        }
    }
    sourceSets {
        main {
            manifest.srcFile('/src/main/MineManifest.xml')
            java.srcDir('/src/main/helo')
            res.srcDir('/src/main/haha')
            aidl.srcDir('/src/main/hello')
        }
        baiduStaging {
            manifest.srcFile('/src/main/MineManifest.xml')
            java.srcDir('/src/main/helo')
            res.srcDir('/src/baiduStaging/haha')
            aidl.srcDir('/src/main/hello')
        }
        wandoujiaStaging {
            manifest.srcFile('/src/main/MineManifest.xml')
            java.srcDir('/src/main/helo')
            res.srcDir('/src/wandoujiaStaging/haha')
            aidl.srcDir('/src/main/hello')
        }
    }
    productFlavors {
        wandoujia {
        }
        baidu {
        }
        productFlavors.all {
            flavor->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
}</span>

大家注意flavor和build type組合的方式:flavors後面跟build type,builed type首字母大寫,比如這裡的:wandoujiaStaging,baiduStaging

第二部:修改目錄

看一下圖就明白了:


第三步:修改資源

現在只把引用程式的圖示和名字給替換掉,這裡不多說,我想大家都會弄。其中標題在string.xml下,圖示在mipmap-xxhdpi目錄下,大家注意他們的合併方式,前面都講過了。

第四步:生成apk

直接執行gradle assemblestaging

第五步: 簽名並安裝

第六步:成果展示:

baidu:

圖示                                      介面


wandoujia:

圖示                                  介面

4 多個模組

4.1新增一個android app

多模組的工程就是在專案的根目錄下有多個module,在android studio下這很簡單:

比如就你現在有一個這樣的工程:



你只需要做一件事::在你的工程上右鍵,選擇新建mudole。

是的就這麼簡單,現在看看工程的樣子:


是的,這個時候,settings.gradle中多了一項,他就是我們新加的module的名字,它其實就是工程頂層目錄下的一個目錄的名字。這個名字你可以隨便改,module你也可以隨便加。

4.2新增一個java library 及其他

新增一個java library時,需要修改module下的build.gradle,修改後看起來應該這樣:

<span style="font-size:14px;">apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}</span>

在android studio中,這些都不用你來做,和建立一個app一樣,你只需要在專案名字上右鍵,選件new,然後接著選擇java library就可以了,其他的建立方式都類似,你只需要知道他們的build.gradle是不同的,然後在必要的時候自定義的去配置他們。

相關推薦

詳細配置android studiogradle

這篇部落格著重點在詳細的介紹如何配置gradle,實現諸如多渠道打包,一次生成不同UI的多渠道apk,自定義資源目錄等。如果你對gradle還沒有比較清晰的認識,那麼推薦你在看這篇部落格之前,先看下我的另一篇部落格理解與配置android studio的gradle,這篇

Android studiogradle配置打jar包和生成Javadoc文件

Android studio 中生成Javadoc 使用Android studio提供的生成Javadoc的方法(之前沒有想要使用這種方式的原因是因為當時以為使用這種方式的話每次生成都需要選擇想要生成的java檔案, 過於麻煩), 最後發現, 使用這種方式只有配置過一次規則之後, 這個規則

理解與配置Android studiogradle

使用gradle構建android應用時,你總是需要這樣一個檔案:build.gradle。你應該已經看過這個檔案了,如果沒有看過的話,你現在就可以看一下,它沒有多少內容。它的簡潔性得益於它提供了很多對設定和屬性的預設值。gradle是基於groovy語言的,不過如果只是用

新裝Android StudioGradle下載慢、Could not get resource 'https://jcenter.bintray.com/...'問題

Gradle是一個版本控制以及靈活構建app的應用,但Gradle的使用有很多坑: 比如Android Studio(以下簡稱AS)在構建第一個新工程的時候自動下載gradle速度很慢.. 或者Gradle在自動下載網路庫的時候經常Could not get resource 'https:

Android StudioGradle自定義APK名稱及輸出路徑

使用AndroidStudio生成Android APK時候,往往需要指定APK輸出路徑及重新命名APK。 因此在Gradle中編碼,以實現上述需求: android { ...// 省略已存在程式碼 applicationVariants.all {

Android Studio gradle 的為什麼有兩個版本號

情景再現 最近開啟Android Studio說要更新專案Gradle版本至4.6,結果build.gradle裡面是這樣的: dependencies { classpath 'com

Android StudioGradle版本和Gradle外掛版本問題

在as中主要是配置gradle和android gradle外掛,注意了gradle和(android gradle外掛)一定不能混為一談,2者是有區別的。 1.gradle的配置 當我們在setting下gradle下設定gradle選擇“use defalut gra

Android Studiogradle構建依賴JCenter下載太慢的解決方案

方案一:將jcenter下載由https修改為http,即由https://jcenter.bintray.com/調整http://jcenter.bintray.com/。 在build.gradle裡,增加jcenter(){url 'http://jcenter/bi

android studiogradle更新辦法

更新方法: 第一步:在你所在專案資料夾下:你專案根目錄\gradle\wrapper\gradle-wrapper.properties 修改gradle-wrapper.properties最後

mac os x下配置Android Studio本地gradle

新建Android studio的專案,開啟專案的gradle.wrapper包裡面的gradle-wrapper.properties檔案,會看到如下內容 distributionBase=GRADLE_USER_HOME distributionPath

Android-studioGradle ’X’ project refresh failed,Error:Connection refused的解決辦法

 問題:在區域網環境下android studio工程同步Gradle時失敗,出現如下圖所示(配置kotlin外掛也可參考此處):   仔細觀察會發現同步每次都是在如下圖所示的階段失敗的:   解決:解決辦法請安如下步驟執行,注意順序: 1),準備資源:準備andro

Android StudioGradle使用詳解

一)基本配置 build配置 buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' } }Android指令碼apply

Android StudioGradle版本和Gradle外掛版本問題整理

    使用Android Studio時,我們有時候需要檢視Gradle版本,具體如何檢視呢!經過如下幾步操作就可以了。     1.啟動Android Studio,選擇一個專案(Module),開啟該專案,如下所示:       2.專案開啟後,單擊‘File’選單,

Android Studio gradle 構建 堆疊空間不足

Please refer to the user guide chapter on the daemon at http://gradle.org/docs/2.2.1/userguide/gradle_daemon.html

Android StudioModule下的gradle檔案的基本配置

本文將介紹平常android開發當中專案module的gradle檔案中的基本配置(不包含建立的library進行上傳到jcenter的指令碼配置),以及針對一些常見的問題進行說明。歡迎加入交流群:微信群(AndroidRunner )、QQ群(314896948) 歡迎關

Android studio 配置Gradle 根據不同引數打包,並在程式碼使用

筆記 使用案例 app/gradle 配置 我們在 thinker中不難看出 他們也是使用了這個方式 android { defaultConfig {

android studio配置X5 webview時的一個坑

這也 default ips build 找到 沒有 androi lte sed 在接入X5的第二步中,需要配置so文件,這裏說一下遇到的坑 1. 需要把demo下載回來,不然你找不到so文件,找到so文件後放到自己相對應的目錄下邊,自己裏面那個目錄也沒有,所以和文件夾一

android studio 的build.gradle

studio rain const list for config cep ets brush apply plugin: ‘com.android.application‘ android { compileSdkVersion 26 defaultCo

Android Studio由於gradle插件版本和gradle版本對應關系導致的編譯失敗的問題

解決 壓縮 tools log 報錯 spa tool sts 報錯信息 今天在Android Studio中導入新項目,import之後編譯報錯,報錯信息基本都是和版本相關,查詢gradle版本相關知識,了解到gradle插件版本和gradle版本有相應的匹配關系,對應如

android studiogradle配置成本地離線zip包

html onu androi com 1.5.0 str 技術 5.0 使用場景 原文:【android studio】 gradle配置成本地離線zip包 關鍵詞:dist