使用建構變數建立不同版本的應用程式

1. 簡介

上次更新時間:2022 年 4 月 14 日

建構變數很適合用來建立不同的應用程式版本。舉例來說,您可能會想建立免費但內容受限的應用程式版本,以及另一個含有更多內容的付費版本。您也可以根據 API 等級或其他裝置版本,建立適用於不同裝置的應用程式版本。

在本程式碼研究室中,您將修改在「單元 1:Kotlin 基本概念」中建立的建構的 Dice Roller 應用程式,因此會產生兩種版本:「試用版」和「完整版」。「完整版」會提供額外的文字方塊,用文字顯示擲骰子的結果,讓使用者不必只靠骰子的圖片來判斷擲出的結果。

須知事項

您應具備:

  • 已完成 Android 基本概念學習課程 1 到 4。如要瞭解程式碼研究室的必備概念,請參閱「單元 1:Kotlin 基本概念」課程。
  • 大致瞭解 Android 建構系統。如要深入瞭解主要元件,請參閱「建構總覽」。

課程內容

  • 何謂建構變數。
  • 何謂來源集。
  • 如何使用建構變數和來源集建立不同版本的應用程式。
  • 如何為應用程式變化版本指定專屬的應用程式 ID。

您將建構的內容

在本程式碼研究室中,您會從「單元 1:Kotlin 基本概念」學習課程中建立的 DiceRoller 應用程式開始操作。DiceRoller 應用程式有一張骰子的圖片,圖片下方有一個「ROLL」按鈕。當使用者按一下「ROLL」,系統會擲骰子,並根據擲骰子的結果來變更圖片。

您可以建立其他專案檔案並新增程式碼,以便完成以下目標:

  • 為應用程式建立「試用版」和「完整版」變種版本。
  • 建立對應變種版本的「試用版」和「完整版」來源集。
  • 在應用程式「完整版」的版面配置中加入方塊。
  • 設計「完整版」方塊,以便在使用者點選「ROLL」時顯示結果。
  • 為應用程式的「試用版」和「完整版」自訂應用程式名稱。
  • 為應用程式的「試用版」和「完整版」提供專屬應用程式 ID。

完整版應用程式如下圖所示:

含有動態方塊的 DiceRoller 應用程式。

事前準備

2. 設定環境

取得程式碼

如果您尚未在「單元 1:Kotlin 基本概念」中完成可立即使用的 DiceRoller 應用程式,請從 GitHub 下載應用程式的程式碼

如要在 Android Studio 中下載並開啟應用程式的程式碼,請按照下列步驟操作:

  1. android-basics-kotlin-dice-roller-with-images-app-solution GitHub 存放區首頁中,依序按一下「Code」>「Download ZIP」
  2. 下載 ZIP 檔案後,請在 Android Studio 中開啟專案,然後依序按一下「File」>「Open」。您可以使用「Empty Activity」新建專案,或是在系統提示時開啟先前專案。由於我們會開啟已下載的專案,因此何種選擇皆不會有太大影響。
  3. 前往 ZIP 檔案下載的位置 (可能位於 Downloads 資料夾),選取該檔案然後按一下「Open」

使用「專案」檢視畫面

處理建構變數時,您必須在「Project」檢視畫面中使用專案檔案,才能查看不同變數的所有目錄。方法是在 Android Studio 中開啟「Project」 窗格,按一下檢視畫面類型選單 (預設為「Android」 檢視畫面),然後選取「Project」檢視畫面。

3. 瞭解建構變數

建構變數是「變種版本」和「建構類型」不同組合的結果。您可以將變種版本視為更符合使用者需求的屬性,建構類型則是更符合開發人員需求的屬性。事實上,您並未直接設定建構變數,而是設定一組變種版本和一組建構類型,藉此決定建構變數。

具體來說,建構變數代表了各項變種版本和建構類型的組合,並據此命名為 <product-flavor><build-type>。舉例來說,如果您的建構類型為 debugrelease,而變種版本為 demofull,則產生的建構變數為:

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

接著我們來設定 DiceRoller 應用程式的變種版本和建構類型。

4. 設定變種版本

變種版本指的是更符合使用者需求的應用程式屬性,因為這類版本通常代表的是提供給使用者的應用程式版本。要建立應用程式的試用版和完整版,您必須新增兩個變種版本,並將其指派至「版本維度」。如要加入變種版本,請開啟應用程式層級的 build.gradle 檔案 (位於「Project」檢視畫面中的「app」>「build.gradle」),然後將這段程式碼貼到 android {} 區塊。

flavorDimensions "app_type"
productFlavors {
   demo {
       dimension "app_type"
         }
   full {
       dimension "app_type"
   }
}

這段程式碼的作用如下:

  • 建立名為「app_type」的版本維度。
  • 建立兩個變種版本,分別代表 demo {}full {} 區塊。
  • 將兩個變種版本指派至 app_type 維度 (如果只有一個版本維度,可以視情況選用)。

這是定義變種版本所需的基本程式碼。之後您會在這個程式碼研究室中使用一些其他選項。

5. 設定建構類型

建構類型是指更符合開發人員需求的屬性,這類屬性通常代表的是開發階段 (例如偵錯、測試版和發布)。Android Studio 會自動為您設定兩種建構類型:debugreleasedebug 建構類型是用於偵錯,release 建構類型則是用於發布。

只要在應用程式層級的 build.gradle 檔案中編輯 buildTypes {} 區塊,即可建立建構類型及修改其設定。預設的 buildTypes {} 區塊樣式如下:

buildTypes {
   release {
       minifyEnabled false
       proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
   }
}

您可以查看 release 建構類型的預設設定 (我們在本程式碼研究室中並未涵蓋 minifyEnabledproguardFiles 屬性)。根據預設,debug 建構類型不會顯示在版本設定檔中,但您可以新增 debug {} 區塊,用來新增或變更某些設定。預設設定可滿足我們的需求,因此您不用修改設定。

6. 使用「Build Variants」工具視窗

現在您有了兩個變種版本和兩種建構類型,讓我們來檢視各個版本產生的建構變數。如何在 Android Studio 中查看新的建構變數:

  1. 在工具列中,按一下「Sync Project with Gradle Files」圖示4e7fbf18152549d8.png。每當您變更建構設定檔時,Studio 都會提示您同步處理檔案,以便系統儲存新的建構設定,並檢查是否有建構錯誤。
  2. 按一下「Build」>「Build Variant」 (或依序前往「View」>「Tool Windows」>「Build Variants」),系統會顯示「Build Variants」視窗。
  3. 在「Active Build Variant」欄位中按一下「demoDebug」,開啟包含您所有建構變數的選單:「demoDebug」、「demoRelease」、「fullDebug」和「fullRelease」。使用此選單即可選取要執行及測試的各種建構變數。

顯示「Active Build Variant」選單的「Build Variants」工具視窗。

執行 demoDebugfullDebug 建構變數 (以 release 建構類型為基礎的變數需要執行更多設定,因此我們不會在本程式碼研究室中處理這類變數)。目前從使用者的角度來看,無法區分 demoDebugfullDebug 建構變數。

7. 為不同變化版本建立不同功能

現在您有了試用版和完整版應用程式,我們來為完整版應用程式加入一些功能。

使用來源集新增付費功能

我們來為 full 變種版本加入一個方塊,用來顯示擲骰子的結果,使用者就不必只靠骰子的圖片來判斷擲出的結果。如要新增這項付費功能,請使用「來源集」。來源集是一個目錄,包含了特定建構類型、變種版本和建構變數的內容。預設的 main 來源集 (「app」>「src」>「main」) 中具有要在所有建構變數之間共用的內容。其他來源集中的內容可能會覆寫這個預設內容。

要如何覆寫 main 來源集中的內容,並決定您需要新增哪些來源集,取決於您要變更的內容。

如要變更資源,例如版面配置或圖片 (位於「main」>「res」),請按照以下一般步驟操作:

  1. 為您要變更的變種版本建立來源集或目錄 (我們會在下一節說明來源集的建立位置和建立方式)。
  2. 將您要變更的資源檔案貼到這個新的來源集中,然後更新來源集。當 Android Gradle 外掛程式 (AGP) 根據新的來源集建立了建構變數,新來源集中的來源程式碼會覆寫 main 中的來源程式碼。

如要覆寫 Java 或 Kotlin 類別中的行為 (位於「main」>「java」),請按照下列一般步驟操作:

  1. 為您要變更的變種版本「以及所有位於相同版本維度中的其他變種版本」建立來源集或目錄。
  2. 將您要變更的檔案貼到所有變種版本來源集中,然後修改您要變更的複本。
  3. main 來源集中刪除原始檔案。

如要在應用程式完整版中加入動態方塊,建議您將付費功能視為兩個主要的編輯項目:

  • 自訂版面配置:修改 activity_main.xml 檔案來新增方塊。
  • 自訂應用程式行為:修改 MainActivity.kt 檔案,讓方塊根據擲骰子的結果變更顯示內容。

在下一節中,您將瞭解建立來源集的位置和方式。

決定建立新來源集的位置

Android Gradle 外掛程式 (AGP) 會說明如何為各個建構類型、變種版本和建構變數組織檔案。如要在 full 變種版本中加入付費功能 (包括對 MainActivity.kt 檔案進行的變更),請一併為 fulldemo 變種版本建立來源集。如要瞭解這些來源集的建立位置,請在 Android Studio 中按照下列步驟操作:

  1. 按一下 IDE 視窗中的「Gradle」
  2. 依序前往「MyApplication」(我的應用程式) >「Tasks」(工作) >「Android」,然後按兩下「sourceSets」(來源集)。如果沒看到「Tasks」資料夾,請依序點選「File」>「Settings」>「Experimental」並且取消勾選「Do not build Gradle task list during Gradle sync」,讓 Gradle 在同步處理期間建立工作清單 (如果是 Mac 作業系統,請依序前往「Android Studio」>「Preferences」>「Experimental」)。Gradle 執行工作後,「Run」視窗應該會顯示輸出內容。
  3. 如果顯示畫面不是如下所示的文字模式,請按一下「Run」 視窗中的「Toggle view」82487fd4e011f105.png

在「Run」視窗中,您應該會看到以下輸出內容:

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

...

debug
-----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

...

full
----
Compile configuration: fullCompile
build.gradle name: android.sourceSets.full
Java sources: [app/src/full/java]
Kotlin sources: [app/src/full/kotlin, app/src/full/java]
Manifest file: app/src/full/AndroidManifest.xml
Android resources: [app/src/full/res]
Assets: [app/src/full/assets]
AIDL sources: [app/src/full/aidl]
RenderScript sources: [app/src/full/rs]
JNI sources: [app/src/full/jni]
JNI libraries: [app/src/full/jniLibs]
Java-style resources: [app/src/full/resources]

「debug」底下的檔案路徑清單說明了在預設值下,AGP 會在哪裡尋找「debug」變種版本的應用程式程式碼和資源。同樣地,「full」底下的檔案路徑清單說明了在預設值下,AGP 會在哪裡尋找「full」變種版本的內容。

記下「Java sources」(例如 Java 和 Kotlin 類別的檔案) 以及「Android resources」(例如版面配置和圖片) 的檔案路徑。現在您已經知道建立新來源集的位置,可以建立這些來源集,並為付費功能新增程式碼了。

自訂完整版的版面配置

如要在完整版應用程式中新增方塊,請按照下列步驟操作:

首先,請建立 full 來源集和 Java 資源目錄:

  1. 開啟「Project」窗格,然後點選「Project」檢視畫面。
  2. 前往 DiceRoller/app/src/ 目錄。
  3. src 目錄上按一下滑鼠右鍵,然後依序點選「New」>「Directory」
  4. 從「Gradle Source Sets」下方的選單中選取「full/resources」,然後按下 Enter 鍵。

接下來,將 activity_main.xml 檔案從 main 來源集貼到 full 來源集。

  1. 前往 DiceRoller/app/src/main/res/
  2. activity_main.xml 檔案上按一下滑鼠右鍵,然後點選「Copy」。
  3. 前往 DiceRoller/app/src/full/res/
  4. res 目錄上按一下滑鼠右鍵,然後點選「Paste」

第三,如要在應用程式的 full 版本中加入方塊,請在 full 來源集的 activity_main.xml 檔案中加入以下程式碼:

<TextView
    android:id="@+id/resultTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:text="Result"
    app:layout_constraintBottom_toTopOf="@+id/button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/imageView" />

執行應用程式的 fullDebugdemoDebug 建構變數 (在「Build Variants」 工具視窗中選取要執行的建構變數,然後按一下「Run」)。您應該只會看到 fullDebug 變數的新方塊。不過,目前這個方塊沒有任何作用,因此我們要進行設計,讓方塊內容根據擲骰子的結果進行變更。

含有方塊的 DiceRoller 應用程式,方塊上顯示的「Result」(結果) 做為預留位置。

自訂完整版的行為

如果是完整版應用程式,方塊應該要用文字顯示擲骰子的結果。如要設定這個行為,請按照下列步驟操作:

首先,請建立 full 來源集 Java 來源目錄。

  1. 在「Project」 檢視畫面的「Project」窗格中,前往 DiceRoller/app/src/full 目錄。
  2. full 目錄上按一下滑鼠右鍵,然後依序點選「New」>「Directory」
  3. 在「Gradle Source Sets」選單中,點選「java」,然後按下 Enter 鍵。

接著,建立 debug 來源集和 Java 來源目錄。

  1. 在「Project」 檢視畫面的「Project」窗格中,前往 DiceRoller/app/src 目錄。
  2. src 目錄上按一下滑鼠右鍵,然後依序點選「New」>「Directory」
  3. 在「Gradle Source Sets」選單中,點選「debug/java」,然後按下 Enter 鍵。

第三,前往 DiceRoller/app/src/main/java 目錄。

  1. MainActivity.kt 檔案貼到 full/javadebug/java 目錄中。
  2. 從主要來源集中刪除 java 目錄,包括 MainActivity.kt 檔案。(在 java 目錄上按一下滑鼠右鍵,然後按一下「Delete」)。
  3. 在「full」來源集 MainActivity.kt 檔案中,將下列程式碼加進 rollDice() 方法:
// Update the result text view
val resultTextView: TextView = findViewById(R.id.resultTextView)
resultTextView.text = when (diceRoll) {
    1 -> "One"
    2 -> "Two"
    3 -> "Three"
    4 -> "Four"
    5 -> "Five"
    else -> "Six"
}

再次執行 fullDebugdemoDebug 建構變數。完整版中的方塊應該會包含擲骰子的結果。

含有動態方塊的 DiceRoller 應用程式。

變更應用程式名稱

為求明確,我們要在應用程式名稱中指定您目前使用的應用程式版本。事實上,這類變更無需來源集即可完成。應用程式名稱是定義在 AndroidManifest.xml 檔案 (「app」>「manifests」>「AndroidManifest.xml」) 中的 label 屬性。如要讓 label 值根據執行中的變化版本進行變更,請開啟 AndroidManifest.xml 檔案,並將標籤行變更為:

android:label="${appLabel}"

這個程式碼會指派 appLabel 變數做為應用程式名稱。

接著,如要設定 appLabel 的值或變更試用版應用程式的名稱,請將 manifestPlaceholders 行新增至您先前建立的 demo {} 區塊:

demo {
   dimension "version"
   manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
   applicationIdSuffix ".demo"
}

同樣地,如要變更應用程式 full 變種版本的名稱,請將另一行 manifestPlaceholders 加進 full {} 區塊:

full {
   dimension "version"
   manifestPlaceholders = [appLabel: "Dice Roller - Full"]
   applicationIdSuffix ".full"
}

接著,再次執行 demoDebugfullDebug 變數。現在不同的建構變數應該會顯示不同的名稱。

已完成含有動態方塊的 DiceRoller 應用程式。

8. 為建構變數指定專屬應用程式 ID

當您建立應用程式的 APK 或 AAB 時,建構工具會使用應用程式 ID 標記應用程式,這個 ID 是由應用程式層級 build.gradle 檔案中的 defaultConfig {} 區塊所定義 (如下所示)。不過,如果您想讓應用程式在 Google Play 商店中顯示不同版本 (例如「試用版」或「完整版」),就必須為每個版本提供不同的應用程式 ID。您可以重新定義 productFlavors {} 區塊中各變種版本的 applicationId 屬性,也可以使用 applicationIdSuffix 在預設的應用程式 ID 上附加片段,如下所示:

defaultConfig {
   applicationId "com.example.diceroller"
   ...
}

flavorDimensions "version"
productFlavors {
   demo {
 dimension "version"
       manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
         applicationIdSuffix ".demo"
   }
   full {
       dimension "version"
       manifestPlaceholders = [appLabel: "Dice Roller - Full"]
         applicationIdSuffix ".full"
   }
}

9. 恭喜

恭喜!您已成功使用建構變數建立兩個版本的 DiceRoller 應用程式!

您設定了用來建立建構變數的變種版本和建構類型。您使用來源集在應用程式「完整版」中新增了付費功能。您已瞭解如何為每個建構變數提供專屬的應用程式 ID,如此一來,Play 商店就會將這類版本視為個別的應用程式。

現在您已瞭解建立多個應用程式版本所需的基本步驟,能為不同的使用者群組提供更加適合的應用程式版本。

後續步驟

參考文件