使用Gradle構建Android程序

jopen 9年前發布 | 45K 次閱讀 Gradle Android開發 移動開發

使用Gradle構建Android程序by Rinvay.T

Android Studio正式版早已經發布了,默認使用Gradle構建,GitHub上80%的Android項目也都是使用Gradle構建的,我們還有什么理由不使用Gradle呢?

環境要求

  • JDK 下載地址
  • Android SDK 下載地址
  • Gradle 下載地址1下載地址2
  • </ul>

    給一個國內的下載地址:AndroidDevTools

    開始(改造Eclipse項目)

    eclipse可以直接用adt導出為gradle項目,android studio直接創建gradle項目。但是,我們還是有必要了解下手動改造,這讓我們更清楚每個文件的作用。

    獨立項目構建

    在我的另一篇博客Gradle插件用戶指南(譯)中,3.1節可以看到,
    一個最簡單的build.gradle文件是這樣的:

    buildscript {
        repositories {
            jcenter()
        }

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

    }

    apply plugin: 'com.android.application'

    android { compileSdkVersion 19 buildToolsVersion "22.0.1" }</pre>

    這里,要求項目目錄結構是gradle的默認目錄:

    project-root  
        |-src
            |-main
                |-java
                |-res
                    |-drawable
                    |-layout
                    |-values
                |-AndroidManifest.xml

    如果是eclipse下的項目,需要配置下項目目錄,修改后的build.gradle文件是這樣的:

    buildscript {
        repositories {
            jcenter()
        }

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

    }

    apply plugin: 'com.android.application'

    android { compileSdkVersion 19 buildToolsVersion "22.0.1"

    sourceSets {
        main{
            manifest.srcFile 'AndroidManifest.xml'
    
            java.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
    
            res.srcDirs = ['res']
    
            assets.srcDirs = ['assets']
    
            jniLibs.srcDirs = ['libs']
    
        }
    }
    
    dependencies {
        compile fileTree(dir:'libs', include:['*.jar'])
    }
    

    }</pre>

    把這個build.gradle拷貝到項目根目錄下,就可以使用gradle來構建你的app了。

    打開終端/命令行,切換到項目根目錄,運行gradle assemble,在main-project/build/outputs/apk下就可以看到生成的apk文件

    Note:
    要注意原項目的依賴,比如 ApiDemos ,是依賴support-v4的,要添加到dependencies中。

    compile 'com.android.support:support-v4:19.0.0'

    多項目構建

    如果程序是由多個子工程構成的話,上面的build.gradle文件就不夠用了。

    假設你的項目目錄是這樣的

    root
        |-main-project
        |-library-project1
        |-library-project2

    并且,依賴關系如下:

    main-project -> library-project1
    library-project1 -> library-project2

    那么,Gradle構建文件應該包含以下幾個文件:

    settings.gradle  
    build.gradle  
    main-project/build.gradle  
    library-project1/build.gradle  
    library-project2/build.gradle

    文件位置是這樣:

    root
        |-main-project
            |- ...
            |-build.gradle
        |-library-project1
            |- ...
            |-build.gradle
        |-library-project2
            |- ...
            |-build.gradle
        |-build.gradle
        |-settings.gradle

    文件內容如下:

    • settings.gradle:

      include ':main-project','library-project1','library-project2'
      </li> </ul>

      settings.gradle聲明了程序包含的子項目,如果子項目時包含在三級子目錄下,例如root/library/library-project1,那么聲明是這樣的:

      ':library:library-project1'

      • build.gradle:

        buildscript {
              repositories {
                  jcenter()
              }
              dependencies {
                  classpath 'com.android.tools.build:gradle:1.0.0'
              }
          }

        根目錄下的buidle.gradle聲明了項目的編譯環境,指定了Android Gradle插件的版本。和上一個章節,那個單一的build.gradle的前半部分內容是一樣的。

        </li>

      • main-project/build.gradle:

        apply plugin: 'com.android.application'

        android { compileSdkVersion 19 buildToolsVersion "22.0.1"

          sourceSets {
              main{
                  manifest.srcFile 'AndroidManifest.xml'
        
                  java.srcDirs = ['src']
                  aidl.srcDirs = ['src']
                  renderscript.srcDirs = ['src']
        
                  res.srcDirs = ['res']
        
                  assets.srcDirs = ['assets']
        
                  jniLibs.srcDirs = ['libs']
        
              }
          }
        
          dependencies {
              compile fileTree(dir:'libs', include:['*.jar'])
              compile project(':library-project1')
          }
        

        }</pre></li> </ul>

        這個build.gradle的內容與上一章節build.gradle的后半部分基本一致,只是多了一個庫項目依賴的聲明。
        這里假設目錄結構和eclipse下的android項目目錄結構是一樣的,如果實際目錄和gradle的默認目錄結構一樣,可以去掉sourceSets{...}部分

        • library-project1/build.gradle和main-project/build.gradle基本一致,只有兩個地方不一樣。

          • apply plugin: 'com.android.application'改成apply plugin: 'com.android.library'
          • compile project(':library-project1')改成compile project(':library-project2')
          • </ul> </li>

          • library-project1/build.gradle和library-project2/build.gradle基本一致,只有一個地方不一樣。

            • 去掉compile project(':library-project2')
            • </ul> </li> </ul>

              至此,多項目的工程完成了gradle改造,可以在項目根目錄下運行gradle assemble進行構建了。

              構建的其他細節,請參考我的另一篇博客Gradle插件用戶指南(譯)

              gradle wrapper

              和Eclipse導出或者Android Studio創建的項目相比,我們改造完的項目還差了幾個文件。
              在項目根目錄下,運行終端命令gradle wrapper,就會生成下面幾個文件:

              project-root
                  |-gradle
                      |-wrapper
                          |-gradle-wrapper.jar
                          |-gradle-wrapper.properties
                  |-gradlew
                  |-gradlew.bat

              gradlew,gradlew.bat是支持多平臺的gradle運行命令,如果運行時,發現系統沒有對應版本的gradle,會通過gradle-wrapper.jar下載gradle-wrapper.properties中指定的gradle版本。這樣的話,任何人獲取代碼后,不用安裝gradle,就可以構建工程

              生成的gradle-wrapper.properties文件中指定的版本,就是運行gradle wrapper命令時的gradle版本。

              通過gradlew,可以執行gradle構建任務,例如:

              ./gradlew assemble

              使用Android Studio

              Android Studio創建的項目默認使用Gradle構建,并且目錄結構也是Gradle默認的。

              使用Android Studio 創建 Android 項目

              這個很簡單,新建項目,按照引導一步一步往下走就行了。

              新建項目的結構如下:

              project-root
                  |-app
                      |-src
                          |-androidTest
                          |-main
                              |-java
                              |-res
                              |-AndroidManifest.xml
                      |-build.gradle
                  |-gradle
                      |-wrapper
                          |-gradle-wrapper.jar
                          |-gradle-wrapper.properties
                  |-build.gradle
                  |-gradle.properties
                  |-gradlew
                  |-gradlew.bat
                  |-local.properties
                  |-settings.gradle

              app
              是項目代碼和資源目錄

              gradlew,gradlew.bat,gradle/wrapper
              上一章節已經介紹過了

              build.gradle,settings.gradle
              上一章節已經介紹過了

              gradle.properties
              gradle運行的參數

              local.properties
              本地環境參數,例如android sdk路徑:sdk.dir

              導入Gradle項目到Android Studio

              對于非Android Studio項目,完成gradle改造后,可以導入到Android Studio中。

              File -> Open...  
              或者Android Studio啟動頁的  
              Open an existing Android Studio project

              直接選擇打開項目根目錄下的settings.gradle(如果沒有的話,打開build.gradle)文件,或者setting.gradle文件的父目錄,結果如下圖:

              image

              如果運行過前面的gradle wrapper命令的話(或者是由eclipse導出的gradle項目),目錄下有wrapper文件夾,Use default gradle wrapper(recommanded)選項就是可選的,否則只能選擇Use local gradle distribution。

              混淆與簽名

              請看我另一篇博客 Gradle插件用戶指南(譯) 3.4.3節和3.4.4節

              構建多渠道包

              動態替換AndroidManifest.xml中的文本

              以友盟為例,是通過在AndroidManifest.xml中添加meta-data標簽來區分渠道:

              <meta-data
                  android:name="UMENG_CHANNEL"
                  android:value="official" />

              不同的value值對應不同的渠道。

              android gradle plugin從0.13.0版本開始,productFlavor開始支持manifestPlaceHolder,我們使用這個就可以實現友盟的多渠道打包。

              1. 修改AndroidManifest.xml,添加placeHolder變量

                <meta-data
                     android:name="UMENG_CHANNEL"
                     android:value="${channel_param}" />
                </li>

              2. 配置build.gradle文件

                android {
                     ...
                     defaultConfig {
                         ...
                         manifestPlaceholders = [channel_param: "official"]
                     }

                 productFlavors {
                     channel1 {
                         ...
                     }
                     ...
                     channelN {
                         ...
                     }                
                 }
                
                 productFlavors.all {
                     flavor -> flavor.manifestPlaceholders = [channel_param: name]
                 }
                
                

                }</pre>

                productFlavors.all是合并的寫法,也可以分開寫:

                channel1 {
                     manifestPlaceholder = [channel_param:name]
                 }
                </li> </ol>

                再進一步,國內的應用商店可以說數以百計,如果每個都在build.gradle文件里寫一個flavor,那么build.gradle文件就會變得冗長。
                我們把渠道號寫到一個單獨的文件里channels.txt,內容如下:

                channel-360
                channel-baidu

                然后在build.gradle里定義函數flavors(),作用就是根據channels.txt里的內容動態創建productFlavor,然后在build.gradle中調用這個函數,優化后的結果是這樣:

                android {
                    ...
                    defaultConfig {
                        ... 
                        manifestPlaceholders = [channel_param: "official"]
                    }

                flavors()
                

                }

                def flavors() { def path = './channels.txt' //channels.txt的路徑 file(path).eachLine { line -> if(!line.startsWith("http://")) { //動態創建productFlavor android.productFlavors.create(line, { manifestPlaceholders = [channel_param: name] })

                    }
                }
                

                }</pre>

                在Android Studio中,點擊Sync Project with Gradle Files,就可以在Gradle窗口中看到相應的渠道構建任務了.

                來自:http://rinvay.github.io/android/2015/04/09/Build-Android-with-Gradle/

                </span>

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