1. 程式人生 > >使用Gradle自動化構建多型別apk包

使用Gradle自動化構建多型別apk包


對於多種型別的apk包構建,通常有以下需求:

  • 各版本有不同的程式碼、資源
  • 上述程式碼中各版本有不同的依賴
  • 各版本有不同的Manifest中元素需求
  • 各版本有不同的proGuard

Android Studio中使用Gradle編譯多種apk包需要靠productFlavors或者buildTypes實現,如果有兩種product flavor和兩種build type,則他們可以生成2*2=4種不同型別的apk包。下文主要使用productFlavors自定義apk內容,而buildTypes使用預設配置用於處理debug版本和release版本。

以下依次來看這4點怎樣實現



一、不同的程式碼和資源

要實現build時使用不同的程式碼和資源:

  1. 在build檔案中定義productFlavors
  2. 為每個Flavor建立對應的資料夾
  3. 將每個Flavor特有的檔案放入資料夾
1.在build檔案中定義productFlavors
...
android {
    ...
    defaultConfig { ... }
    signingConfigs { ... }
    buildTypes { ... }
    productFlavors {
        demo {
            applicationId "com.buildsystemexample.app.demo"
            versionName "1.0-demo"
        }
        full {
            applicationId "com.buildsystemexample.app.full"
            versionName "1.0-full"
        }
    }
}
...

其中defaultConfig{}中為預設值,productFlavors{}會複寫所有可以複寫的值。



2.為每個Flavor建立對應的資料夾

在上面兩個Flavor的基礎上,假設你想在每個Flavor使用不同的SecondActivity檔案,按照下面的步驟:

  1. 展開app目錄
  2. 右擊src目錄,選擇New>Directory
  3. 輸入Flavor的名字,也就是demo,新建
  4. 在demo中建立以下資料夾 app/src/demo/java app/src/demo/res app/src/demo/res/layout app/src/demo/res/values 如下圖:

PS:上述過程就是將預設的main下的目錄結構複製過來,想新增其他資源也是同樣的操作



3. 將每個Flavor特有的檔案放入資料夾

向上一步新建的目錄中,先在java目錄下建立對應的package,向其中放入SecondActivity.java和其layout檔案,並在res目錄下新增本Flavor的AndroidManifest.xml檔案。Manifest的merge規則見下文。

另外一種方法是右擊app目錄,選擇新增Activity,在引導介面中最後一項Target Source Set選擇你想新增到的Flavor,Android Studio就會自動為你生成對應的AndroidManifest,不過需要稍加修改。

在新增demo所需檔案後,為了新增full所需檔案和包,需要在Android Studio中將build variants切換為fullDebug,否則Android Studio不會將full下的java目錄識別為原始檔目錄,導致不能新增package。

對於demo和full中對應的相同的檔案,注意要保證包名的相同,否則main中程式碼對於不同部分的引用,會因為有不同包名而失敗。



二、不同的依賴

在build.gradle中,使用Flavor名+Compile來規定特定Flavor所需依賴:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    demoCompile 'com.android.support:design:22.2.0'
    fullCompile 'com.jakewharton:butterknife:6.1.0'
}


三、不同的Manifest需求

Manifest可以通過Merge的方式合併多個Manifest源。通常來說,有三種類型manifest檔案需要被merge到最終的結果apk,下面是按照優先權排序:

  1. productFlavors和buildTypes中所指定的manifest檔案
  2. 應用主manifest檔案
  3. 庫manifest檔案

簡單來說,manifest的merge會將每個元素及其子元素的節點和屬性進行合併。

例如:

<activity
   android:name=”com.foo.bar.ActivityOne”
 android:theme=”@theme1”/>

<activity
   android:name=”com.foo.bar.ActivityOne”
 android:screenOrientation=”landscape/>

合併會成為

<activity
   android:name=”com.foo.bar.ActivityOne”
 android:theme=”@theme1”
 android:screenOrientation=”landscape/>

不過

<activity
   android:name=”com.foo.bar.ActivityOne”
 android:theme=”@theme1”/>

 <activity
   android:name=”com.foo.bar.ActivityOne”
 android:theme=”@theme2”
 android:screenOrientation=”landscape/>

合併會產生一個衝突,因為都有theme,而theme的屬性不同。

要了解manifest合併的更高階應用,檢視Manifest Merger




四、不同ProGuard需求
android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFile getDefaultProguardFile('proguard-android.txt')
        }
    }

    productFlavors {
        flavor1 {
        }
        flavor2 {
            proguardFile 'some-other-rules.txt'
        }
    }
}

Android Studio將使用所有的定義在相應buildTypes和相應productFlavors中的規則檔案。

有兩個預設的規則檔案:

  • proguard-android.txt
  • proguard-android-optimize.txt 存放在SDK中。可以使用getDefaultProguardFile()來獲得檔案的完整路徑,他們除了優化的開啟是否不同之外都相同。