1. Giới thiệu
Ngày cập nhật gần đây nhất: Ngày 14/04/2022
Các biến thể bản dựng rất hữu ích trong việc tạo nhiều phiên bản ứng dụng. Ví dụ: bạn có thể muốn tạo một phiên bản ứng dụng miễn phí với nội dung giới hạn và một phiên bản trả phí khác gồm nhiều nội dung hơn. Bạn cũng có thể tạo các phiên bản ứng dụng khác nhau hướng đến các thiết bị khác nhau, dựa trên cấp độ API hoặc các biến thể thiết bị khác.
Trong lớp học lập trình này, bạn sẽ sửa đổi ứng dụng Dice Roller (Đổ xúc xắc) đã tạo trong Bài 1: Kiến thức cơ bản về Kotlin để có hai phiên bản: "bản minh họa" và "bản đầy đủ". "Bản đầy đủ" có hộp văn bản bổ sung hiển thị kết quả của xúc xắc bằng chữ, nó cho người dùng biết kết quả gieo không chỉ dựa vào hình ảnh xúc xắc.
Những điều bạn nên biết
Bạn phải:
- Hoàn thành lộ trình học Khái niệm cơ bản về Android 1-4. Để tham gia các lớp học lập trình về điều kiện tiên quyết, vui lòng xem lộ trình Bài 1: Khái niệm cơ bản về Kotlin.
- Hiểu biết chung về hệ thống bản dựng Android. Để hiểu rõ các thành phần chính, vui lòng xem lại phần tổng quan về bản dựng.
Kiến thức bạn sẽ học được
- Định nghĩa về biến thể xây dựng.
- Nhóm tài nguyên là gì?
- Cách tạo các phiên bản khác nhau của ứng dụng bằng biến thể bản dựng và nhóm tài nguyên.
- Cách cung cấp mã ứng dụng duy nhất cho các biến thể của ứng dụng.
Sản phẩm bạn sẽ tạo ra
Trong lớp học lập trình này, bạn bắt đầu bằng ứng dụng DiceRoller đã tạo trong nội dung lộ trình học của Bài 1: Khái niệm cơ bản về Kotlin. Ứng dụng DiceRoller có ảnh của con xúc xắc và nút ROLL (đổ xúc xắc) bên dưới. Khi người dùng nhấp vào ROLL (đổ xúc xắc), xúc xắc được gieo và hình ảnh thay đổi tùy thuộc vào kết quả của nó.
Bạn tạo các tệp dự án bổ sung và thêm mã vào:
- Tạo các phiên bản sản phẩm cho "bản minh họa" và "bản đầy đủ" của ứng dụng.
- Tạo nhóm tài nguyên "bản minh họa" và "bản đầy đủ" tương ứng với các phiên bản sản phẩm.
- Thêm hộp vào bố cục trong "bản đầy đủ" của ứng dụng.
- Lập trình hộp "bản đầy đủ" để hiển thị kết quả đổ xúc xắc khi người dùng nhấp vào ROLL. (đổ xúc xắc)
- Tùy chỉnh tiêu đề ứng dụng cho "bản minh họa" và "bản đầy đủ".
- Cung cấp mã ứng dụng duy nhất cho ứng dụng của "bản minh họa" và "bản đầy đủ".
Phiên bản đầy đủ của ứng dụng sẽ có dạng như sau:
Bạn cần có
2. Thiết lập môi trường
Lấy mã
Nếu bạn không có sẵn ứng dụng DiceRoller hoàn chỉnh từ Bài 1: Kiến thức cơ bản về Kotlin, vui lòng tải mã ứng dụng trong GitHub xuống.
Để tải xuống và mở mã ứng dụng trong Android Studio, hãy làm theo các bước sau:
- Trên trang chủ của kho lưu trữ
android-basics-kotlin-dice-roller-with-images-app-solution
GitHub, hãy nhấp vào Mã > Tải xuống tệp ZIP. - Sau khi tệp ZIP được tải xuống, hãy mở dự án trong Android Studio rồi nhấp vào Tệp > Mở. Bạn có thể bắt đầu một Hoạt động trống hoặc mở dự án trước đó nếu được nhắc. Điều đó không thực sự quan trọng vì chúng tôi sẽ mở dự án đã tải xuống.
- Chuyển đến nơi tải tệp ZIP xuống (có thể là thư mục
Downloads
), chọn tệp rồi nhấp vào Mở.
Sử dụng Chế độ xem dự án
Khi xử lý các biến thể bản dựng, bạn cần giữ tệp dự án ở chế độ xem Dự án để xem tất cả thư mục cho các biến thể khác nhau. Để thực hiện việc này, hãy mở ngăn Dự án trong Android Studio, nhấp vào trình đơn loại chế độ xem (theo mặc định, tùy chọn này được đặt thành chế độ xem Android) rồi chọn chế độ xem Dự án.
3. Tìm hiểu về biến thể bản dựng
Các biến thể bản dựng là kết hợp của tổ hợp các phiên bản sản phẩm khác nhau và loại bản dựng. Bạn có thể coi phiên bản sản phẩm là thuộc tính chuyên dành cho người dùng, còn loại bản dựng dành cho nhà phát triển nhiều hơn. Bạn không cần định cấu hình trực tiếp các biến thể bản dựng; thay vào đó, hãy định cấu hình một tập hợp các phiên bản sản phẩm và một tập hợp các loại bản dựng để lần lượt xác định các biến thể bản dựng.
Cụ thể, các biến thể bản dựng đại diện cho mọi tổ hợp phiên bản sản phẩm và loại bản dựng, đồng thời được đặt tên tương ứng là <product-flavor><build-type>
. Ví dụ: nếu bạn có các loại bản dựng debug
và release
cùng với phiên bản sản phẩm demo
và full
, thì các biến thể bản dựng thu được sẽ là:
demoDebug
demoRelease
fullDebug
fullRelease
Hãy định cấu hình phiên bản sản phẩm và các loại bản dựng cho ứng dụng DiceRoller.
4. Định cấu hình phiên bản sản phẩm
Phiên bản sản phẩm là các thuộc tính của ứng dụng hướng tới giao diện người dùng nhiều hơn, theo đó chúng thường đại diện cho phiên bản ứng dụng hiển thị cho người dùng. Để tạo bản minh họa và bản đầy đủ của ứng dụng, bạn phải thêm hai phiên bản sản phẩm và chỉ định chúng cho một nhóm phiên bản. Để thêm phiên bản sản phẩm, hãy mở tệp build.gradle
cấp ứng dụng (app > build.gradle ở chế độ xem Project) và dán mã này vào khối android {}
.
flavorDimensions "app_type"
productFlavors {
demo {
dimension "app_type"
}
full {
dimension "app_type"
}
}
Mã này sẽ thực hiện những việc sau:
- Tạo một nhóm phiên bản có tên là
app_type
. - Tạo hai phiên bản sản phẩm, đại diện bằng khối
demo {}
vàfull {}
. - Chỉ định 2 phiên bản sản phẩm cho thứ nguyên
app_type
(không bắt buộc nếu chỉ có một nhóm phiên bản).
Đây là mã cơ bản cần thiết để xác định phiên bản sản phẩm. Bạn sẽ sử dụng một số tùy chọn bổ sung sau trong lớp học lập trình này.
5. Định cấu hình loại bản dựng
Loại bản dựng là các thuộc tính của ứng dụng hướng tới nhà phát triển nhiều hơn, theo đó chúng thường đại diện cho các giai đoạn phát triển (ví dụ: gỡ lỗi, thử nghiệm và phát hành). Android Studio sẽ tự động định cấu hình hai loại bản dựng cho bạn: debug
và release
. Loại bản dựng debug
dành cho mục đích gỡ lỗi, trong khi loại bản dựng release
dành cho mục đích phân phối.
Bạn có thể tạo các loại bản dựng và sửa đổi cấu hình của chúng bằng cách chỉnh sửa khối buildTypes {}
trong tệp build.gradle
cấp ứng dụng. Khối buildTypes {}
mặc định có dạng như sau:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Bạn có thể xem cấu hình mặc định cho loại bản dựng release
(chúng tôi sẽ không đề cập đến thuộc tính minifyEnabled
hoặc proguardFiles
trong lớp học lập trình này). Theo mặc định, loại bản dựng debug
không xuất hiện trong tệp cấu hình bản dựng, nhưng bạn có thể thêm một khối debug {}
để bổ sung hoặc thay đổi một số chế độ cài đặt nhất định. Cấu hình mặc định hoạt động đáp ứng các mục đích của chúng tôi, vì vậy bạn phải giữ nguyên cấu hình này.
6. Sử dụng cửa sổ công cụ Biến thể bản dựng
Bây giờ, bạn đã có hai phiên bản sản phẩm và hai loại bản dựng, hãy cùng xem những biến thể bản dựng nào được tạo ra. Cách xem các biến thể bản dựng mới trong Android Studio:
- Trên thanh công cụ, hãy nhấp vào Đồng bộ hóa dự án với tệp Gradle . Bất cứ khi nào bạn thực hiện thay đổi đối với tệp cấu hình, Studio sẽ nhắc bạn đồng bộ hóa tệp để có thể lưu cấu hình bản dựng mới và kiểm tra lỗi bản dựng.
- Nhấp vào Tạo > Chọn Biến thể bản dựng (hoặc Xem > Của sổ công cụ > Biến thể bản dựng để hiển thị cửa sổ Biến thể bản dựng.
- Nhấp vào demoDebug trong cột Biến thể bản dựng đang hoạt động để mở một trình đơn có chứa tất cả các biến thể bản dựng: demoDebug, demoRelease, fullDebug, và fullRelease. Sử dụng trình đơn này chọn các biến thể bản dựng khác nhau để chạy và thử nghiệm.
Chạy các biến thể demoDebug
và fullDebug
(việc chạy các biến thể dựa trên loại bản dựng release
yêu cầu thiết lập nhiều hơn nên chúng ta sẽ không đề cập đến chúng trong lớp học lập trình này). Cho đến nay, người dùng vẫn chưa phân biệt được các biến thể demoDebug
và fullDebug
.
7. Tạo các tính năng khác nhau cho các biến thể khác nhau
Hiện bạn đã có phiên bản ứng dụng minh họa và đầy đủ, hãy thêm một số tính năng vào phiên bản đầy đủ.
Thêm tính năng nâng cao bằng cách sử dụng nhóm tài nguyên
Đối với phiên bản sản phẩm full
, hãy thêm hộp hiển thị kết quả đổ xúc xắc để người dùng không chỉ dựa vào hình ảnh xúc xắc mới biết kết quả đã gieo được. Để thêm tính năng cao cấp này, bạn cần sử dụng nhóm tài nguyên. Nhóm tài nguyên là một thư mục chứa nội dung cho các loại bản dựng cụ thể, phiên bản sản phẩm và các biến thể của bản dựng. Nhóm tài nguyên main
mặc định (ứng dụng > src > chính) chứa nội dung có thể chia sẻ giữa tất cả các biến thể bản dựng. Nội dung mặc định này có thể bị ghi đè bởi nội dung trong các nhóm tài nguyên khác.
Cách bạn ghi đè nội dung trong nhóm tài nguyên main
và xác định nhóm tài nguyên cần thêm sẽ khác nhau tùy thuộc vào nội dung bạn muốn thay đổi.
Để thay đổi một tài nguyên, chẳng hạn như bố cục hoặc hình ảnh (nội dung trong phần main > res), hãy làm theo các bước chung sau:
- Tạo một nhóm tài nguyên hoặc thư mục cho phiên bản sản phẩm mà bạn muốn thay đổi (chúng tôi sẽ trình bày vị trí và cách tạo nhóm tài nguyên này trong phần tiếp theo).
- Dán tệp tài nguyên mà bạn muốn thay đổi vào nhóm tài nguyên mới này rồi cập nhật. Khi trình bổ trợ Android cho Gradle (AGP) tạo một biến thể bản dựng phụ thuộc vào nhóm tài nguyên mới, thì biến đó sẽ ghi đè mã tài nguyên trong
main
bằng mã tài nguyên trong nhóm tài nguyên mới.
Để ghi đè một hành vi trong lớp Java hoặc Kotlin (nội dung trong main > java), hãy làm theo các bước chung sau:
- Tạo nhóm tài nguyên hoặc thư mục, cho phiên bản sản phẩm mà bạn muốn thay đổi và tất cả các phiên bản sản phẩm khác có cùng nhóm phiên bản.
- Dán tệp bạn muốn thay đổi vào tất cả các nhóm tài nguyên phiên bản sản phẩm, sau đó sửa đổi bản sao (hoặc các bản sao) bạn muốn thay đổi.
- Xóa tệp gốc khỏi nhóm tài nguyên
main
.
Để thêm một hộp động vào phiên bản đầy đủ của ứng dụng, bạn nên coi tính năng cao cấp này là hai nội dung chỉnh sửa chính:
- Tùy chỉnh bố cục: Thêm một hộp bằng cách sửa đổi tệp
activity_main.xml
. - Tùy chỉnh hành vi của ứng dụng: Thay đổi nội dung hiển thị trong hộp dựa trên con xúc xắc bằng cách sửa đổi tệp
MainActivity.kt
.
Ở phần tiếp theo, bạn sẽ tìm hiểu vị trí và cách tạo nhóm tài nguyên.
Xác định nơi tạo nhóm tài nguyên mới
Trình bổ trợ Android cho Gradle (AGP) cho bạn biết cách sắp xếp các tệp theo từng loại bản dựng, phiên bản sản phẩm và biến thể bản dựng. Để thêm một tính năng cao cấp vào phiên bản sản phẩm full
bao gồm thay đổi đối với tệp MainActivity.kt
, bạn sẽ tạo nhóm tài nguyên cho cả phiên bản full
và demo
. Để tìm ra nơi tạo các nhóm tài nguyên này, hãy làm theo các bước sau trong Android Studio:
- Nhấp vào Gradle trong cửa sổ IDE.
- Chuyển đến MyApplication > Tasks (Nhiệm vụ) > android rồi nhấp đúp vào sourceSets. Nếu bạn không thấy thư mục Tasks (Nhiệm vụ), hãy để Gradle tạo danh sách việc cần làm trong quá trình đồng bộ hóa bằng cách nhấp vào Tệp > Cài đặt > Thử nghiệm và bỏ đánh dấu ô Không tạo danh sách nhiệm vụ cho Gradle trong quá trình đồng bộ hóa Gradle (Android Studio > Tùy chọn > Thử nghiệm trên macOS). Sau khi Gradle thực thi nhiệm vụ, cửa sổ Run (Chạy) sẽ hiển thị kết quả.
- Nếu màn hình không ở chế độ văn bản như hình dưới đây, hãy nhấp vào Chuyển đổi chế độ xem trong cửa sổ Chạy.
Trong cửa sổ Chạy, bạn sẽ thấy kết quả sau:
------------------------------------------------------------
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]
Danh sách đường dẫn tệp trong mục "gỡ lỗi" mô tả nơi AGP tìm kiếm mã ứng dụng và tài nguyên cho phiên bản sản phẩm "gỡ lỗi" theo mặc định. Tương tự, danh sách đường dẫn tệp trong "bản đầy đủ" mô tả nơi AGP tìm kiếm nội dung cho sản phẩm của "bản đầy đủ" theo mặc định.
Hãy lưu ý đến các đường dẫn tệp "Nguồn Java" (đối với các tệp như lớp Java và Kotlin) và "Tài nguyên Android" (đối với các tệp như bố cục và hình ảnh). Giờ đây, bạn đã biết vị trí để tạo nhóm tài nguyên mới, hãy tạo chúng và thêm mã cho tính năng cao cấp.
Tùy chỉnh bố cục của phiên bản đầy đủ
Để thêm hộp vào phiên bản đầy đủ của ứng dụng, hãy làm theo các bước sau:
Trước tiên, hãy tạo thư mục nguồn full
và thư mục tài nguyên Java:
- Mở ngăn Dự án và chọn chế độ xem Dự án.
- Chuyển đến thư mục
DiceRoller/app/src/
. - Nhấp chuột phải vào thư mục
src
rồi chọn Mới > Thư mục. - Trên trình đơn trong Nhóm tài nguyên Gradle, hãy chọn đầy đủ/tài nguyên rồi nhấn vào
Enter
.
Tiếp theo, dán tệp activity_main.xml
từ nhóm tài nguyên main
thành nhóm tài nguyên full
.
- Chuyển đến
DiceRoller/app/src/main/res/
. - Nhấp chuột phải vào tệp
activity_main.xml
rồi nhấp vào Sao chép. - Chuyển đến
DiceRoller/app/src/full/res/
. - Nhấp chuột phải vào thư mục
res
rồi nhấp vào Dán.
Thứ ba, để thêm một hộp vào phiên bản full
của ứng dụng, hãy thêm mã này vào tệp activity_main.xml
trong nhóm tài nguyên full
:
<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" />
Chạy biến thể bản dựng fullDebug
và demoDebug
của ứng dụng (chọn biến thể bản dựng mà bạn muốn chạy bằng cửa sổ công cụ Biến thể bản dựng, sau đó nhấp vào Chạy). Bạn sẽ thấy hộp mới cho duy nhất biến thể fullDebug
. Tuy nhiên, hộp này chưa thực hiện thao tác nào, vì vậy hãy lập trình để nó thay đổi tùy thuộc vào con xúc xắc.
Tùy chỉnh hành vi của phiên bản đầy đủ
Đối với phiên bản đầy đủ của ứng dụng, hộp sẽ hiển thị kết quả của con xúc xắc bằng chữ. Để lập trình hành vi này, hãy làm theo các bước sau:
Trước tiên, hãy tạo thư mục nguồn Java nhóm tài nguyên full
.
- Trong ngăn Dự án ở chế độ xem Dự án, hãy chuyển đến thư mục
DiceRoller/app/src/full
. - Nhấp chuột phải vào thư mục
full
rồi chọn Mới > Thư mục. - Trên trình đơn Nhóm tài nguyên Gradle, hãy chọn java rồi nhấn vào
Enter
.
Tiếp theo, hãy tạo nhóm tài nguyên debug
và thư mục nguồn Java.
- Trong ngăn Dự án ở chế độ xem Dự án, hãy chuyển đến thư mục
DiceRoller/app/src
. - Nhấp chuột phải vào thư mục
src
rồi chọn Mới > Thư mục. - Trong trình đơn Nhóm tài nguyên Gradle, hãy chọn debug/java, rồi nhấn
Enter
.
Thứ ba, chuyển đến thư mục DiceRoller/app/src/main/java
.
- Dán tệp
MainActivity.kt
vào cả hai thư mụcfull/java
vàdebug/java
. - Xóa thư mục
java
, bao gồm cả tệpMainActivity.kt
khỏi nhóm tài nguyên chính. (Nhấp chuột phải vào thư mụcjava
rồi nhấp vào Delete (Xóa). - Trong tệp
MainActivity.kt
của nhóm tài nguyên phiên bản đầy đủ, hãy thêm mã này vào phương thứcrollDice()
:
// 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"
}
Chạy lại biến thể bản dựng fullDebug
và demoDebug
. Hộp ở phiên bản đầy đủ phải bao gồm kết quả đổ xúc xắc.
Thay đổi tên ứng dụng
Để rõ ràng, hãy xác định phiên bản ứng dụng mà bạn đang sử dụng trong tiêu đề ứng dụng. Loại thay đổi này có thể thực hiện được mà không cần nhóm tài nguyên. Tiêu đề ứng dụng được thuộc tính label
xác định trong tệp AndroidManifest.xml
(ứng dụng > tệp kê khai > AndroidManifest.xml). Để khiến giá trị label
thay đổi tùy thuộc vào biến thể đang chạy, hãy mở tệp AndroidManifest.xml
và thay đổi dòng nhãn thành:
android:label="${appLabel}"
Thao tác này sẽ chỉ định một biến là appLabel
làm tiêu đề ứng dụng.
Tiếp theo, để đặt giá trị của appLabel
hoặc thay đổi tiêu đề cho phiên bản minh họa của ứng dụng, hãy thêm dòng manifestPlaceholders
vào khối demo {}
mà bạn đã tạo trước đó:
demo {
dimension "version"
manifestPlaceholders = [appLabel: "Dice Roller - Demo"]
applicationIdSuffix ".demo"
}
Tương tự như vậy, để thay đổi tiêu đề phiên bản full
của ứng dụng, hãy thêm một dòng manifestPlaceholders
khác vào khối full {}
:
full {
dimension "version"
manifestPlaceholders = [appLabel: "Dice Roller - Full"]
applicationIdSuffix ".full"
}
Bây giờ, hãy chạy lại các biến thể demoDebug
và fullDebug
. Bạn sẽ thấy các tiêu đề khác nhau cho các biến thể bản dựng khác nhau.
8. Cung cấp mã ứng dụng duy nhất cho các biến thể bản dựng của bạn
Khi tạo một tệp APK hoặc AAB cho ứng dụng, các công cụ bản dựng sẽ gắn thẻ bằng mã nhận dạng ứng dụng được xác định trong khối defaultConfig {}
của tệp build.gradle
(như trình bày bên dưới). Tuy nhiên, nếu bạn muốn tạo các phiên bản khác nhau của ứng dụng để xuất hiện dưới dạng danh sách riêng biệt trên Cửa hàng Google Play, chẳng hạn như "bản minh họa" hoặc "bản đầy đủ", bạn cần cung cấp cho mỗi phiên bản một mã ứng dụng khác nhau. Với mỗi phiên bản trong khối productFlavors {}
, bạn có thể xác định lại thuộc tính applicationId
, hoặc thay vào đó bạn có thể bổ sung một mảnh (segment) vào mã nhận dạng ứng dụng mặc định thông qua applicationIdSuffix
như minh họa dưới đây:
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. Xin chúc mừng
Xin chúc mừng! Bạn đã tạo thành công hai phiên bản của ứng dụng DiceRoller sử dụng biến thể bản dựng!
Bạn đã định cấu hình phiên bản sản phẩm và loại bản dựng để tạo biến thể bản dựng. Bạn đã thêm một tính năng cao cấp vào ứng dụng của "bản đầy đủ" bằng cách sử dụng nhóm tài nguyên. Bạn đã tìm hiểu cách cung cấp mã ứng dụng duy nhất cho mỗi biến thể bản dựng để chúng được coi là các ứng dụng riêng biệt trong Cửa hàng Play.
Giờ đây, bạn đã biết các bước cơ bản cần thiết để tạo nhiều phiên bản của một ứng dụng nhằm phục vụ tốt hơn cho các nhóm người dùng khác nhau.