Các biến thể của ấn bản cho phép bạn tạo nên trải nghiệm phù hợp hơn với cá nhân người dùng. Thông qua việc định cấu hình các biến thể ấn bản, bạn có thể phát hành nhiều biến thể bản dựng, mỗi biến thể có các thuộc tính riêng.
Việc phát hành nhiều biến thể bản dựng của thư viện cho phép người dùng lựa chọn những tính năng phù hợp với nhu cầu của họ. Ví dụ: bạn có thể phát hành nhiều cấu phần phần mềm cho loại bản dựng gỡ lỗi và phát hành. Cấu phần phần mềm của ấn bản gỡ lỗi phải có mã ghi nhật ký bổ sung, cũng như các phần phụ thuộc để quá trình ghi nhật ký bổ sung này hoạt động.
Trước khi tiếp tục, hãy đảm bảo rằng bạn chuẩn bị để phát hành thư viện.
Sử dụng siêu dữ liệu của mô-đun Gradle
Để phát hành các biến thể của thư viện, bạn phải sử dụng Siêu dữ liệu của mô-đun Gradle (GMM). GMM mô tả ấn bản của bạn và duy trì hoạt động quản lý phần phụ thuộc nhận biết được biến thể. Theo mặc định, GMM sẽ được phát hành cùng với thư viện.
Sau đây là các lợi ích khi dùng GMM:
- Nếu dùng GMM với Gradle 6.0 trở lên, bạn có thể phát hành nhiều biến thể ấn bản hoặc nhiều cấu phần phần mềm. Mỗi biến thể hoặc mỗi cấu phần phần mềm sẽ có những thuộc tính và phần phụ thuộc riêng. Nếu bạn dùng tệp POM của Maven thay vì GMM, bạn chỉ có thể phát hành một cấu phần phần mềm. Nếu dùng tệp POM, bạn có thể phát hành các cấu phần phần mềm bổ sung bằng thuật toán phân loại, nhưng các cấu phần phần mềm bổ sung không được có các phần phụ thuộc riêng.
- Gradle tự động tạo một biến thể cho quá trình biên dịch và một cho thời gian chạy, mỗi biến thể có các phần phụ thuộc riêng. Bạn có thể phát hành một biến thể cho quá trình biên dịch và một cho thời gian chạy để người dùng có thể lựa chọn tuỳ theo thời điểm họ sử dụng thư viện của bạn. GMM cho phép người tiêu dùng xem các phần phụ thuộc khác nhau để biên dịch và
thời gian chạy, dựa trên việc sử dụng
api
,implementation
hoặccompileOnly
/runtimeOnly
. Xem Cấu hình phần phụ thuộc để có danh sách đầy đủ các phần phụ thuộc. Bạn có thể thực hiện việc này ngay cả khi chỉ phát hành một biến thể ấn bản. - Khi sử dụng môi trường thử nghiệm cố định, bạn có thể xuất bản một biến thể bổ sung với các phiên bản siêu dữ liệu hoặc chức năng cho phép người tiêu dùng chọn sản phẩm đó. Bạn có thể thực hiện việc này ngay cả khi chỉ phát hành một biến thể ấn bản.
Tìm hiểu về biến thể ấn bản
Để hiểu cách hoạt động của các biến thể ấn bản, bạn cần tìm hiểu của Gradle các bước phát hành cơ bản. Sau đây là một số khái niệm chính về ấn bản:
- Biến thể bản dựng: Là cấu hình mà Gradle dùng để tạo thư viện; đây là sản phẩm kết hợp giữa loại bản dựng và phiên bản sản phẩm. Để tìm hiểu thêm, hãy xem phần Bảng thuật ngữ về bản dựng Android.
- Cấu phần phần mềm: Tệp hoặc thư mục mà bản dựng tạo ra. Trong ngữ cảnh phát hành thư viện, cấu phần phần mềm thường là tệp JAR hoặc AAR.
- Biến thể ấn bản: Là cấu phần phần mềm có các phần phụ thuộc, tính năng và thuộc tính có liên quan. Xin lưu ý rằng Gradle gọi các biến thể ấn bản là biến thể. Tuy nhiên, tài liệu này sẽ dùng tên gọi biến thể ấn bản để phân biệt với biến thể bản dựng.
- Thuộc tính: Gradle dùng thuộc tính để xác định và chọn biến thể ấn bản khi có nhiều lựa chọn. Ví dụ:
org.gradle.usage=java-api
vàorg.gradle.jvm.version=11
là các thuộc tính của biến thể. - Thành phần phần mềm: Là một đối tượng trong Gradle có thể lưu giữ một hoặc nhiều biến thể ấn bản và được phát hành cho một tập toạ độ Maven duy nhất (
groupdId:artifactId:version
). Thành phần phần mềm hiển thị trong DSL của Gradle thông quaProject.getComponents()
. - Ấn bản: Là những thứ được phát hành vào kho lưu trữ và người dùng sẽ sử dụng. Các ấn bản có chứa một thành phần phần mềm và siêu dữ liệu của thành phần đó, chẳng hạn như mã nhận dạng (
groupId:artifactId:version
).
Trình bổ trợ Android cho Gradle (AGP) 7.1 ra mắt ngôn ngữ miền chuyên biệt (DSL) để kiểm soát xem biến thể bản dựng nào được dùng trong quá trình phát hành và biến thể nào bị bỏ qua. DSL cho phép bạn tạo các thực thể của SoftwareComponent
có chứa:
- Một biến thể ấn bản từ một biến thể bản dựng
- Nhiều biến thể ấn bản từ nhiều biến thể bản dựng
Khi tạo thành phần phần mềm có nhiều biến thể ấn bản, AGP sẽ thiết lập các thuộc tính trên từng biến thể để người dùng có thể chọn đúng biến thể họ cần. Những thuộc tính này được lấy trực tiếp từ loại bản dựng và phiên bản mà bạn dùng để tạo biến thể bản dựng. Nếu tạo thành phần chỉ có một biến thể ấn bản duy nhất thì không cần dùng đến các thuộc tính vì không phải phân biệt biến thể.
Tạo thành phần phần mềm chỉ có một biến thể ấn bản
Đoạn mã sau đây định cấu hình thành phần phần mềm có một biến thể ấn bản được tạo từ biến thể bản dựng release
, cũng như thêm JAR nguồn làm cấu phần phần mềm phụ:
Kotlin
android { publishing { singleVariant("release") { withSourcesJar() } } }
Groovy
android { publishing { singleVariant('release') { withSourcesJar() } } }
Bạn có thể tạo nhiều thành phần, mỗi thành phần có một biến thể ấn bản, sau đó phân phối các thành phần đó trên nhiều toạ độ Maven. Trong trường hợp này, thuộc tính sẽ không được đặt trên biến thể ấn bản. Bạn không thể biết được rằng biến thể ấn bản này là của biến thể bản dựng release
nếu chỉ nhìn vào siêu dữ liệu của ấn bản. Vì chỉ có một biến thể ấn bản có liên quan, nên bạn không cần phân biệt.
Tạo một thành phần phần mềm có nhiều biến thể ấn bản
Bạn có thể chọn tất cả hoặc một nhóm nhỏ các biến thể bản dựng để đưa vào một thành phần phần mềm. AGP sẽ tự động dùng tên loại bản dựng, tên phiên bản sản phẩm và tên nhóm phiên bản sản phẩm để tạo các thuộc tính sao cho dự án đang dùng có thể phân biệt các biến thể.
Để phát hành tất cả biến thể bản dựng trong một thành phần, hãy chỉ định allVariants()
trong khối multipleVariants{}
của tệp build.gradle
ở cấp độ mô-đun:
Kotlin
android { publishing { multipleVariants { allVariants() withJavadocJar() } } }
Groovy
android { publishing { multipleVariants { allVariants() withJavadocJar() } } }
Đoạn mã này sẽ tạo một thành phần duy nhất có tên default
. Để đặt tên khác cho
thành phần, hãy dùng multipleVariants({name})
.
Trong trường hợp này, tất cả loại bản dựng và nhóm phiên bản sản phẩm được dùng làm thuộc tính.
Bạn cũng có thể chọn biến thể bạn muốn phát hành bằng cách dùng includeBuildTypeValues()
và includeFlavorDimensionAndValues()
:
Kotlin
android { publishing { multipleVariants("custom") { includeBuildTypeValues("debug", "release") includeFlavorDimensionAndValues( dimension = "color", values = arrayOf("blue", "pink") ) includeFlavorDimensionAndValues( dimension = "shape", values = arrayOf("square") ) } } }
Groovy
android { publishing { multipleVariants('custom') { includeBuildTypeValues('debug', 'release') includeFlavorDimensionAndValues( /*dimension =*/ 'color', /*values =*/ 'blue', 'pink' ) includeFlavorDimensionAndValues( /*dimension =*/ 'shape', /*values =*/ 'square' ) } } }
Trong ví dụ này, thành phần tuỳ chỉnh chứa tất cả các tổ hợp của (debug
, release
) đối với loại bản dựng, (blue
, pink
) đối với nhóm color
và (square
) đối với nhóm shape
.
Bạn phải liệt kê tất cả các nhóm phiên bản, kể cả khi bạn chỉ phát hành một giá trị của một nhóm, để AGP biết cần phải dùng giá trị nào cho mỗi nhóm.
Bảng sau liệt kê biến thể ấn bản tạo ra và các thuộc tính có liên quan của biến thể đó.
Biến thể | Thuộc tính |
---|---|
blueSquareDebug | com.android.build.api.attributes.BuildTypeAttr ="debug"
com.android.build.api.attributes.ProductFlavorAttr:color ="blue" |
blueSquareRelease |
com.android.build.api.attributes.BuildTypeAttr="release"
|
pinkSquareDebug |
com.android.build.api.attributes.BuildTypeAttr="debug"
|
pinkSquareRelease |
com.android.build.api.attributes.BuildTypeAttr="release"
|
Trong thực tế, có nhiều biến thể được phát hành. Ví dụ: mỗi biến thể trong số các biến thể ở trên sẽ được phát hành 2 lần, một lần cho quá trình biên dịch và một lần cho thời gian chạy, với các phần phụ thuộc khác nhau (tuỳ vào việc các phần phụ thuộc đã khai báo dùng implementation
hay api
) và với giá trị khác nhau cho thuộc tính org.gradle.Usage
. Tuy nhiên, cấu phần phần mềm (tệp AAR) của 2 biến thể này là như nhau.
Để biết thêm thông tin, hãy xem
tài liệu về API publishing
.
Vấn đề về khả năng tương thích để phát hành thư viện nhiều phiên bản
Một dự án sử dụng AGP 7.0 trở xuống không thể sử dụng các thư viện đa phiên bản đã phát hành
với AGP 7.1 trở lên. Đây là vấn đề đã biết do thay đổi về thuộc tính
tên cho nhóm phiên bản sản phẩm từ dimensionName
đến
com.android.build.api.attributes.ProductFlavor:dimensionName
trong AGP 7.1.
Tuỳ thuộc vào cách thiết lập dự án, bạn có thể sử dụng missingDimensionStrategy
trong
API biến thể cũ có hoạt động không
xung quanh vấn đề này.
Ví dụ: giả sử dự án ứng dụng của bạn chỉ có một phiên bản sản phẩm nhóm phiên bản:
Kotlin
android {
applicationVariants.forEach { variant ->
val flavor = variant.productFlavors[0].name
val attributePrefix = "com.android.build.api.attributes.ProductFlavor"
val dimensionName = "version"
variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
}
}
Groovy
android {
applicationVariants.forEach { variant ->
def flavor = variant.getProductFlavors()[0].name
def attributePrefix = "com.android.build.api.attributes.ProductFlavor"
def dimensionName = "version"
variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
}
}