Định cấu hình bản dựng

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Hệ thống xây dựng Android biên soạn tài nguyên và mã nguồn của ứng dụng rồi đóng gói chúng vào tệp APK hoặc Android App Bundle mà bạn có thể kiểm thử, triển khai, ký và phân phối.

Android Studio sử dụng Gradle, một bộ công cụ xây dựng nâng cao để tự động hoá và quản lý quy trình xây dựng, đồng thời cho phép bạn xác định những cấu hình bản dựng tuỳ chỉnh một cách linh hoạt. Mỗi cấu hình bản dựng có thể xác định một tập hợp mã và tài nguyên riêng, đồng thời dùng lại những phần mà mọi phiên bản của ứng dụng đều sử dụng. Trình bổ trợ Android cho Gradle phối hợp với bộ công cụ xây dựng để cung cấp các quy trình và chế độ cài đặt có thể định cấu hình dành riêng cho việc xây dựng và kiểm thử các ứng dụng Android.

Gradle và trình bổ trợ Android cho Gradle chạy độc lập với Android Studio. Tức là bạn có thể xây dựng các ứng dụng Android ngay trong Android Studio, dòng lệnh trên máy của mình hoặc trên những máy không cài đặt Android Studio (chẳng hạn như máy chủ tích hợp liên tục).

Nếu không dùng Android Studio, bạn có thể tìm hiểu cách xây dựng và chạy ứng dụng qua dòng lệnh. Cho dù bạn xây dựng dự án qua dòng lệnh, trên một máy từ xa hay sử dụng Android Studio, đầu ra của bản dựng vẫn không đổi.

Lưu ý: Vì Gradle và trình bổ trợ Android chạy độc lập với Android Studio nên bạn cần cập nhật riêng các công cụ xây dựng. Hãy đọc các ghi chú phát hành để tìm hiểu cách cập nhật Gradle và trình bổ trợ Android cho Gradle.

Tính linh hoạt của hệ thống xây dựng Android cho phép bạn tạo các cấu hình xây dựng tuỳ chỉnh mà không cần chỉnh sửa các tệp nguồn cốt lõi của ứng dụng. Trang này sẽ giúp bạn tìm hiểu cách hoạt động của hệ thống xây dựng Android cũng như cách hệ thống này có thể hỗ trợ tuỳ chỉnh và tự động hoá nhiều cấu hình bản dựng. Nếu bạn muốn tìm hiểu thêm về phương pháp triển khai ứng dụng, hãy xem bài viết Tạo và chạy ứng dụng. Còn nếu bạn cần bắt đầu tạo các cấu hình bản dựng tuỳ chỉnh bằng Android Studio ngay tức thì, hãy xem phần Định cấu hình các biến thể bản dựng.

Quy trình xây dựng

Quy trình xây dựng chứa nhiều công cụ và quy trình giúp chuyển đổi dự án ́thành Gói ứng dụng Android (APK) hoặc Android App Bundle (AAB).

Trình bổ trợ Android cho Gradle sẽ thực hiện phần lớn quy trình xây dựng. Tuy nhiên, sẽ rất hữu ích nếu bạn nắm được một số khía cạnh nhất định để có thể điều chỉnh bản dựng cho phù hợp với những yêu cầu của riêng mình.

Mỗi dự án có thể có mục tiêu xây dựng riêng, chẳng hạn như bản dựng cho thư viện bên thứ ba tạo ra thư viện AAR hoặc JAR. Tuy nhiên, ứng dụng là loại dự án phổ biến nhất và bản dựng cho dự án ứng dụng sẽ tạo ra tệp APK hoặc AAB gỡ lỗi hoặc phát hành của ứng dụng. Bạn có thể triển khai, kiểm thử hoặc phát hành những tệp đó cho người dùng bên ngoài.

Trang này tập trung vào phần phát triển ứng dụng nhưng hầu hết các loại bản dựng đều áp dụng những khái niệm và giai đoạn xây dựng tương tự.

Bảng thuật ngữ về bản dựng Android

Gradle và trình bổ trợ Android giúp bạn định cấu hình những phần dưới đây của bản dựng:

Loại bản dựng

Các loại bản dựng xác định một số thuộc tính mà Gradle sử dụng khi xây dựng và đóng gói ứng dụng. Những loại bản dựng này thường được định cấu hình cho từng giai đoạn trong vòng đời phát triển của ứng dụng.

Ví dụ: bản dựng gỡ lỗi kích hoạt các chế độ gỡ lỗi và ký ứng dụng bằng khoá gỡ lỗi trong khi bản dựng phát hành có thể rút gọn, làm rối mã nguồn và ký ứng dụng bằng khoá phát hành để phân phối.

Bạn cần phải xác định ít nhất một loại bản dựng để xây dựng ứng dụng. Theo mặc định, Android Studio sẽ tạo các loại bản dựng gỡ lỗi và phát hành. Để bắt đầu tuỳ chỉnh các chế độ đóng gói cho ứng dụng, hãy tìm hiểu cách định cấu hình loại bản dựng.

Phiên bản sản phẩm
Phiên bản sản phẩm biểu thị những phiên bản của ứng dụng mà bạn có thể phát hành cho người dùng, chẳng hạn như phiên bản miễn phí và phiên bản có tính phí. Bạn có thể tuỳ chỉnh từng phiên bản sản phẩm để vừa sử dụng mã và tài nguyên riêng, vừa chia sẻ và sử dụng lại các phần được dùng trên mọi phiên bản của ứng dụng. Việc xây dựng phiên bản sản phẩm là không bắt buộc và bạn cần phải tự mình tạo những phiên bản như vậy. Để bắt đầu tạo các phiên bản ứng dụng, hãy tìm hiểu cách định cấu hình phiên bản sản phẩm.
Biến thể bản dựng
Biến thể bản dựng là một sản phẩm vừa là bản dựng vừa là phiên bản sản phẩm, đồng thời là cấu hình mà Gradle sử dụng để xây dựng ứng dụng. Bằng cách sử dụng biến thể bản dựng, bạn có thể xây dựng phiên bản gỡ lỗi cho phiên bản sản phẩm trong quá trình phát triển cũng như phiên bản phát hành đã ký của phiên bản sản phẩm cho việc phân phối. Tuy không trực tiếp định cấu hình biến thể bản dựng, bạn vẫn có thể định cấu hình các loại bản dựng và phiên bản sản phẩm cấu thành nên những biến thể bản dựng đó. Việc tạo thêm các loại bản dựng hoặc phiên bản sản phẩm cũng tạo ra những biến thể bản dựng bổ sung. Để tìm hiểu cách tạo và quản lý các biến thể bản dựng, hãy tham khảo phần tổng quan về Định cấu hình các biến thể bản dựng.
Các mục trong tệp kê khai
Bạn có thể chỉ định giá trị cho một số thuộc tính của tệp kê khai trong cấu hình biến thể bản dựng. Các giá trị xây dựng này sẽ ghi đè các giá trị hiện có trong tệp kê khai. Việc này rất hữu ích nếu bạn muốn tạo nhiều biến thể của ứng dụng bằng tên ứng dụng, phiên bản SDK tối thiểu hoặc phiên bản SDK mục tiêu riêng. Khi có nhiều tệp kê khai, công cụ sáp nhập tệp kê khai sẽ sáp nhập các chế độ cài đặt tệp kê khai.
Phần phụ thuộc
Hệ thống xây dựng quản lý các phần phụ thuộc của dự án qua hệ thống tệp cục bộ và kho lưu trữ từ xa. Nhờ đó, bạn không cần phải tìm kiếm, tải và sao chép thủ công những gói tệp nhị phân của các phần phụ thuộc vào thư mục dự án. Để tìm hiểu thêm, hãy tham khảo phần Thêm phần phụ thuộc của bản dựng.
Hệ thống xây dựng cho phép bạn chỉ định các chế độ ký trong cấu hình bản dựng. Đồng thời, hệ thống này cũng có thể tự động ký ứng dụng trong quy trình xây dựng. Hệ thống xây dựng ký phiên bản gỡ lỗi bằng một khoá và chứng chỉ mặc định, sử dụng thông tin đăng nhập đã biết để tránh hiện lời nhắc nhập mật khẩu tại thời điểm xây dựng. Hệ thống xây dựng không ký phiên bản phát hành trừ phi bạn xác định rõ cấu hình ký cho bản dựng đó. Nếu không có khoá phát hành, bạn có thể tạo một khoá như mô tả trong phần Ký ứng dụng. Ứng dụng bắt buộc phải có bản dựng bản phát hành đã ký để được phân phối qua hầu hết các cửa hàng ứng dụng.
Rút gọn mã và tài nguyên
Hệ thống xây dựng cho phép bạn chỉ định cho mỗi biến thể xây dựng một tệp quy tắc ProGuard riêng. Khi bạn xây dựng ứng dụng, hệ thống xây dựng sẽ áp dụng một bộ quy tắc phù hợp để rút gọn mã và tài nguyên bằng các công cụ rút gọn tích hợp sẵn, chẳng hạn như R8. Việc thu hẹp mã và tài nguyên có thể giúp giảm kích thước tệp APK hoặc AAB.
Hỗ trợ nhiều tệp APK
Hệ thống xây dựng cho phép bạn tự động xây dựng nhiều tệp APK, trong đó mỗi tệp APK chỉ chứa mã và tài nguyên cần thiết cho một mật độ màn hình hoặc Giao diện nhị phân của ứng dụng (ABI) cụ thể. Để biết thêm thông tin, hãy xem nội dung Tạo nhiều tệp APK. Tuy nhiên, việc phát hành một tệp AAB duy nhất là phương pháp được đề xuất sử dụng vì phương pháp này cung cấp chức năng phân tách theo ngôn ngữ cũng như mật độ màn hình và ABI, đồng thời tránh việc phải tải nhiều cấu phần phần mềm lên Google Play. Toàn bộ ứng dụng mới được gửi sau tháng 8 năm 2021 đều bắt buộc phải sử dụng tệp AAB.

Tệp cấu hình bản dựng

Việc tạo cấu hình bản dựng tuỳ chỉnh đòi hỏi bạn phải thay đổi ít nhất một tệp cấu hình bản dựng hoặc tệp build.gradle. Các tệp văn bản thuần tuý này sử dụng Ngôn ngữ dành riêng cho miền (DSL) để mô tả và điều khiển logic xây dựng bằng Groovy (một ngôn ngữ động của Máy ảo Java (JVM)) hoặc bằng tập lệnh Kotlin (một phiên bản của ngôn ngữ Kotlin).

Bạn không cần phải nắm rõ cách sử dụng tập lệnh Groovy hoặc Kotlin để bắt đầu định cấu hình bản dựng, vì trình bổ trợ Android cho Gradle sẽ đưa ra hầu hết các phần tử DSL mà bạn cần. Để tìm hiểu thêm về những phần tử DSL của trình bổ trợ Android cho Gradle, hãy đọc tài liệu tham khảo về DSL dành cho Groovy. Tập lệnh Kotlin cũng dựa vào DSL Kotlin cơ bản của Gradle.

Khi bắt đầu một dự án mới, Android Studio sẽ tự động tạo một số tệp như minh hoạ trong hình 1 rồi điền sẵn dữ liệu vào những tệp đó dựa trên những giá trị mặc định thích hợp.

Hình 1. Cấu trúc dự án mặc định của một mô-đun ứng dụng Android.

Một số tệp cấu hình bản dựng Gradle thuộc cấu trúc dự án chuẩn cho một ứng dụng Android. Trước khi bắt đầu định cấu hình bản dựng, bạn cần nắm được phạm vi và mục đích của các tệp này cũng như những phần tử DSL cơ bản mà chúng xác định nên.

Tệp cài đặt Gradle

Tệp settings.gradle (đối với Groovy) hoặc tệp settings.gradle.kts (đối với tập lệnh Kotlin) nằm trong thư mục gốc của dự án. Tệp cài đặt này xác định chế độ cài đặt kho lưu trữ cấp dự án và thông báo cho Gradle những mô-đun cần bổ sung trong quá trình xây dựng ứng dụng. Các dự án chứa nhiều mô-đun cần chỉ định những mô-đun sẽ được đưa vào bản dựng hoàn thiện.

Đối với hầu hết dự án, theo mặc định, tệp này sẽ có dạng như sau:

Groovy

pluginManagement {

    /**
     * The pluginManagement {repositories {...}} block configures the
     * repositories Gradle uses to search or download the Gradle plugins and
     * their transitive dependencies. Gradle pre-configures support for remote
     * repositories such as JCenter, Maven Central, and Ivy. You can also use
     * local repositories or define your own remote repositories. The code below
     * defines the Gradle Plugin Portal, Google's Maven repository,
     * and the Maven Central Repository as the repositories Gradle should use to look for its
     * dependencies.
     */

    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {

    /**
     * The dependencyResolutionManagement {repositories {...}}
     * block is where you configure the repositories and dependencies used by
     * all modules in your project, such as libraries that you are using to
     * create your application. However, you should configure module-specific
     * dependencies in each module-level build.gradle file. For new projects,
     * Android Studio includes Google's Maven repository and the Maven Central
     * Repository by default, but it does not configure any dependencies (unless
     * you select a template that requires some).
     */

    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "My Application"
include ‘:app’

Kotlin

pluginManagement {

    /**
     * The pluginManagement {repositories {...}} block configures the
     * repositories Gradle uses to search or download the Gradle plugins and
     * their transitive dependencies. Gradle pre-configures support for remote
     * repositories such as JCenter, Maven Central, and Ivy. You can also use
     * local repositories or define your own remote repositories. The code below
     * defines the Gradle Plugin Portal, Google's Maven repository,
     * and the Maven Central Repository as the repositories Gradle should use to look for its
     * dependencies.
     */

    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {

    /**
     * The dependencyResolutionManagement {repositories {...}}
     * block is where you configure the repositories and dependencies used by
     * all modules in your project, such as libraries that you are using to
     * create your application. However, you should configure module-specific
     * dependencies in each module-level build.gradle file. For new projects,
     * Android Studio includes Google's Maven repository and the Maven Central
     * Repository by default, but it does not configure any dependencies (unless
     * you select a template that requires some).
     */

    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "My Application"
include(":app")

Tệp bản dựng cấp cao nhất

Tệp build.gradle cấp cao nhất (đối với Groovy) hoặc tệp build.gradle.kts (đối với tập lệnh Kotlin) nằm trong thư mục gốc của dự án. Tệp này xác định những phần phụ thuộc áp dụng cho toàn bộ mô-đun trong dự án. Theo mặc định, tệp bản dựng cấp cao nhất sử dụng khối plugins để xác định các phần phụ thuộc Gradle mà tất cả mô-đun trong dự án đều sử dụng. Ngoài ra, tệp bản dựng cấp cao nhất còn chứa mã để dọn sạch thư mục bản dựng.

Mã mẫu sau đây mô tả các chế độ cài đặt mặc định và phần tử DSL trong tệp build.gradle cấp cao nhất sau khi tạo dự án mới:

Groovy

plugins {

    /**
     * Use `apply false` in the top-level build.gradle file to add a Gradle
     * plugin as a build dependency but not apply it to the current (root)
     * project. Don't use `apply false` in sub-projects. For more information,
     * see Applying external plugins with same version to subprojects.
     */

    id 'com.android.application' version '7.3.0' apply false
    id 'com.android.library' version '7.3.0' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
}

Kotlin

plugins {

    /**
     * Use `apply false` in the top-level build.gradle file to add a Gradle
     * plugin as a build dependency but not apply it to the current (root)
     * project. Don't use `apply false` in sub-projects. For more information,
     * see Applying external plugins with same version to subprojects.
     */

    id("com.android.application") version "7.3.0" apply false
    id("com.android.library") version "7.3.0" apply false
    id("org.jetbrains.kotlin.android") version "1.7.20" apply false
}

Định cấu hình các thuộc tính trên toàn dự án

Đối với các dự án Android chứa nhiều mô-đun, bạn có thể xác định một số thuộc tính ở cấp dự án và chia sẻ những thuộc tính này cho mọi mô-đun. Bạn có thể thực hiện việc này bằng cách thêm các thuộc tính bổ sung vào khối ext trong tệp build.gradle cấp cao nhất (đối với Groovy) hoặc tệp build.gradle.kts (đối với tập lệnh Kotlin):

Groovy

// This block encapsulates custom properties and makes them available to all
// modules in the project. The following are only a few examples of the types
// of properties you can define.
ext {
    sdkVersion = 33
    // You can also create properties to specify versions for dependencies.
    // Having consistent versions between modules can avoid conflicts with behavior.
    appcompatVersion = "1.6.0"
    ...
}
...

Kotlin

// This block encapsulates custom properties and makes them available to all
// modules in the project. The following are only a few examples of the types
// of properties you can define.
ext {
    extra["sdkVersion"] = 33
    // You can also create properties to specify versions for dependencies.
    // Having consistent versions between modules can avoid conflicts with behavior.
    extra["appcompatVersion"] = "1.6.0"
    ...
}
...

Để truy cập vào những thuộc tính này qua một mô-đun trong cùng dự án, hãy sử dụng cú pháp sau đây trong tệp build.gradle của mô-đun đó.

Groovy

android {
    // Use the following syntax to access properties you defined at the project level:
    // rootProject.ext.property_name
    compileSdk rootProject.ext.sdkVersion
    ...
}
...
dependencies {
    implementation "androidx.appcompat:appcompat:${rootProject.ext.appcompatVersion}"
    ...
}

Kotlin

android {
    // Use the following syntax to access properties you defined at the project level:
    // rootProject.extra["property_name"]
    compileSdk = rootProject.extra["sdkVersion"]

    // Alternatively, you can access properties using a type safe delegate:
    val sdkVersion: Int by rootProject.extra
    ...
    compileSdk = sdkVersion
}
...
dependencies {
    implementation("androidx.appcompat:appcompat:${rootProject.ext.appcompatVersion}")
    ...
}

Lưu ý: Tuy Gradle cho phép xác định các thuộc tính trên toàn dự án ở cấp độ mô-đun nhưng bạn nên tránh thực hiện thao tác này do làm như vậy sẽ khiến những mô-đun có chung thuộc tính bị ghép nối với nhau. Tình trạng ghép nối mô-đun khiến cho sau này việc xuất mô-đun dưới dạng dự án độc lập trở nên khó khăn, đồng thời ngăn Gradle sử dụng phương thức thực thi dự án song song để tăng tốc độ tạo các bản dựng có nhiều mô-đun.

Tệp bản dựng cấp mô-đun

Tệp build.gradle cấp mô-đun (đối với Groovy) hoặc build.gradle.kts (đối với tập lệnh Kotlin) nằm trong từng thư mục project/module/. Tệp này cho phép định cấu hình các chế độ cài đặt bản dựng dành riêng cho mô-đun chứa tệp. Việc định cấu hình những chế độ cài đặt bản dựng này cho phép bạn cung cấp các chế độ đóng gói tuỳ chỉnh, chẳng hạn như các loại bản dựng và phiên bản sản phẩm bổ sung, cũng như ghi đè những chế độ cài đặt trong tệp kê khai main/, tệp build.gradle cấp cao nhất hoặc tệp build.gradle.kts.

Tệp build.gradle của mô-đun ứng dụng Android mẫu này nêu ra một số phần tử và chế độ cài đặt DSL cơ bản:

Groovy

/**
 * The first line in the build configuration applies the Android Gradle plugin
 * to this build and makes the android block available to specify
 * Android-specific build options.
 */

plugins {
    id 'com.android.application'
}

/**
 * The android block is where you configure all your Android-specific
 * build options.
 */

android {

    /**
     * The app's namespace. Used primarily to access app resources.
     */

    namespace 'com.example.myapp'

    /**
     * compileSdk specifies the Android API level Gradle should use to
     * compile your app. This means your app can use the API features included in
     * this API level and lower.
     */

    compileSdk 33

    /**
     * The defaultConfig block encapsulates default settings and entries for all
     * build variants and can override some attributes in main/AndroidManifest.xml
     * dynamically from the build system. You can configure product flavors to override
     * these values for different versions of your app.
     */

    defaultConfig {

        // Uniquely identifies the package for publishing.
        applicationId 'com.example.myapp'

        // Defines the minimum API level required to run the app.
        minSdk 21

        // Specifies the API level used to test the app.
        targetSdk 33

        // Defines the version number of your app.
        versionCode 1

        // Defines a user-friendly version name for your app.
        versionName "1.0"
    }

    /**
     * The buildTypes block is where you can configure multiple build types.
     * By default, the build system defines two build types: debug and release. The
     * debug build type is not explicitly shown in the default build configuration,
     * but it includes debugging tools and is signed with the debug key. The release
     * build type applies ProGuard settings and is not signed by default.
     */

    buildTypes {

        /**
         * By default, Android Studio configures the release build type to enable code
         * shrinking, using minifyEnabled, and specifies the default ProGuard rules file.
         */

        release {
              minifyEnabled true // Enables code shrinking for the release build type.
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    /**
     * The productFlavors block is where you can configure multiple product flavors.
     * This lets you create different versions of your app that can
     * override the defaultConfig block with their own settings. Product flavors
     * are optional, and the build system does not create them by default.
     *
     * This example creates a free and paid product flavor. Each product flavor
     * then specifies its own application ID, so that they can exist on the Google
     * Play Store, or an Android device, simultaneously.
     *
     * If you declare product flavors, you must also declare flavor dimensions
     * and assign each flavor to a flavor dimension.
     */

    flavorDimensions "tier"
    productFlavors {
        free {
            dimension "tier"
            applicationId 'com.example.myapp.free'
        }

        paid {
            dimension "tier"
            applicationId 'com.example.myapp.paid'
        }
    }
}

/**
 * The dependencies block in the module-level build configuration file
 * specifies dependencies required to build only the module itself.
 * To learn more, go to Add build dependencies.
 */

dependencies {
    implementation project(":lib")
    implementation 'androidx.appcompat:appcompat:1.6.0'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

Kotlin

/**
 * The first section in the build configuration applies the Android Gradle plugin
 * to this build and makes the android block available to specify
 * Android-specific build options.
 */

plugins {
    id("com.android.application")
}

/**
 * The android block is where you configure all your Android-specific
 * build options.
 */

android {

    /**
     * The app's namespace. Used primarily to access app resources.
     */

    namespace = "com.example.myapp"

    /**
     * compileSdk specifies the Android API level Gradle should use to
     * compile your app. This means your app can use the API features included in
     * this API level and lower.
     */

    compileSdk = 33

    /**
     * The defaultConfig block encapsulates default settings and entries for all
     * build variants and can override some attributes in main/AndroidManifest.xml
     * dynamically from the build system. You can configure product flavors to override
     * these values for different versions of your app.
     */

    defaultConfig {

        // Uniquely identifies the package for publishing.
        applicationId = "com.example.myapp"

        // Defines the minimum API level required to run the app.
        minSdk = 21

        // Specifies the API level used to test the app.
        targetSdk = 33

        // Defines the version number of your app.
        versionCode = 1

        // Defines a user-friendly version name for your app.
        versionName = "1.0"
    }

    /**
     * The buildTypes block is where you can configure multiple build types.
     * By default, the build system defines two build types: debug and release. The
     * debug build type is not explicitly shown in the default build configuration,
     * but it includes debugging tools and is signed with the debug key. The release
     * build type applies ProGuard settings and is not signed by default.
     */

    buildTypes {

        /**
         * By default, Android Studio configures the release build type to enable code
         * shrinking, using minifyEnabled, and specifies the default ProGuard rules file.
         */

        getByName("release") {
            isMinifyEnabled = true // Enables code shrinking for the release build type.
            proguardFiles(
                getDefaultProguardFile("proguard-android.txt"),
                "proguard-rules.pro"
            )
        }
    }

    /**
     * The productFlavors block is where you can configure multiple product flavors.
     * This lets you create different versions of your app that can
     * override the defaultConfig block with their own settings. Product flavors
     * are optional, and the build system does not create them by default.
     *
     * This example creates a free and paid product flavor. Each product flavor
     * then specifies its own application ID, so that they can exist on the Google
     * Play Store, or an Android device, simultaneously.
     *
     * If you declare product flavors, you must also declare flavor dimensions
     * and assign each flavor to a flavor dimension.
     */

    flavorDimensions += "tier"
    productFlavors {
        create("free") {
            dimension = "tier"
            applicationId = "com.example.myapp.free"
        }

        create("paid") {
            dimension = "tier"
            applicationId = "com.example.myapp.paid"
        }
    }
}

/**
 * The dependencies block in the module-level build configuration file
 * specifies dependencies required to build only the module itself.
 * To learn more, go to Add build dependencies.
 */

dependencies {
    implementation(project(":lib"))
    implementation("androidx.appcompat:appcompat:1.6.0")
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Tệp thuộc tính Gradle

Gradle cũng bao gồm 2 tệp thuộc tính nằm trong thư mục của dự án gốc mà bạn có thể dùng để chỉ định các chế độ cài đặt cho chính bộ công cụ xây dựng Gradle:

gradle.properties
Đây là nơi bạn có thể định cấu hình các chế độ cài đặt Gradle trên toàn dự án, chẳng hạn như kích thước tối đa của vùng nhớ khối xếp trong trình nền của Gradle. Để biết thêm thông tin, hãy xem nội dung Môi trường tạo bản dựng.
local.properties
Định cấu hình các thuộc tính môi trường cục bộ cho hệ thống xây dựng, trong đó có:
  • ndk.dir – Đường dẫn đến NDK. Thuộc tính này không được dùng nữa. Mọi phiên bản NDK đã tải xuống đều được cài đặt trong thư mục ndk của thư mục SDK Android.
  • sdk.dir – Đường dẫn đến SDK.
  • cmake.dir – Đường dẫn đến CMake.
  • ndk.symlinkdir – trong Android Studio 3.5 trở lên, tạo ra một đường liên kết tượng trưng đến NDK mà có thể ngắn hơn đường dẫn NDK được cài đặt.

Ánh xạ lại NDK thành một đường dẫn ngắn hơn (chỉ dành cho Windows)

Trên Windows, các công cụ trong thư mục NDK được cài đặt, chẳng hạn như ld.exe, sẽ chuyển thành các đường dẫn dài. Tuy nhiên, những công cụ này không mạnh về mặt hỗ trợ đường dẫn dài.

Để tạo một đường dẫn ngắn hơn, tại local.properties, hãy đặt thuộc tính ndk.symlinkdir để yêu cầu trình bổ trợ Android cho Gradle tạo một đường liên kết tượng trưng đến NDK. Đường dẫn của đường liên kết tượng trưng này có thể ngắn hơn thư mục NDK hiện có. Ví dụ: ndk.symlinkdir = C:\ sẽ tạo ra đường liên kết tượng trưng sau đây: C:\ndk\19.0.5232133

Đồng bộ hoá dự án với các tệp Gradle

Khi bạn điều chỉnh tệp cấu hình bản dựng trong dự án, Android Studio sẽ yêu cầu đồng bộ hoá tệp dự án để có thể nhập các thay đổi về cấu hình bản dựng, đồng thời chạy một số tuỳ chọn kiểm tra nhằm đảm bảo cấu hình không phạm lỗi bản dựng.

Để đồng bộ hoá tệp dự án, hãy nhấp vào Sync Now (Đồng bộ hoá ngay) trong thanh thông báo xuất hiện khi bạn thực hiện thay đổi (như minh hoạ trong hình 2) hoặc nhấp vào biểu tượng Sync Project (Đồng bộ hoá dự án) trên thanh trình đơn. Nếu Android Studio phát hiện lỗi trong cấu hình, chẳng hạn như mã nguồn sử dụng các tính năng API chỉ có ở cấp API cao hơn compileSdkVersion, thì cửa sổMessages (Thông báo) sẽ xuất hiện để mô tả vấn đề.

Hình 2. Đồng bộ hoá dự án với các tệp cấu hình bản dựng trong Android Studio.

Nhóm tài nguyên

Android Studio sẽ nhóm mã nguồn và tài nguyên cho từng mô-đun vào thành các nhóm tài nguyên theo cách hợp lý. Khi bạn tạo mô-đun mới, Android Studio sẽ tạo một nhóm tài nguyên main/ trong mô-đun đó. Nhóm tài nguyên main/ của một mô-đun chứa mã và tài nguyên mà toàn bộ biến thể bản dựng của mô-đun đó sử dụng.

Bạn không bắt buộc phải có các thư mục nhóm tài nguyên bổ sung và Android Studio cũng sẽ không tự động tạo các thư mục này khi bạn định cấu hình các biến thể bản dựng mới. Tuy nhiên, việc tạo nhóm tài nguyên tương tự như main/ sẽ giúp sắp xếp những tệp và tài nguyên mà Gradle chỉ nên sử dụng khi tạo một số phiên bản nhất định của ứng dụng:

src/main/
Nhóm tài nguyên này bao gồm mã và tài nguyên dành cho mọi biến thể bản dựng.
src/buildType/
Tạo nhóm tài nguyên này để chỉ chứa mã và tài nguyên cho một loại bản dựng cụ thể .
src/productFlavor/
Tạo nhóm tài nguyên này để chỉ chứa mã và tài nguyên cho một phiên bản sản phẩm cụ thể .

Lưu ý: Nếu định cấu hình bản dựng để kết hợp nhiều phiên bản sản phẩm, bạn có thể tạo thư mục nhóm tài nguyên cho từng tổ hợp phiên bản sản phẩm giữa các nhóm phiên bản: src/productFlavor1ProductFlavor2/

src/productFlavorBuildType/
Tạo nhóm tài nguyên này để chỉ chứa mã và tài nguyên cho một biến thể bản dựng cụ thể.

Ví dụ: để tạo phiên bản "fullDebug" của ứng dụng, hệ thống xây dựng hợp nhất mã, chế độ cài đặt và tài nguyên lấy từ các nhóm tài nguyên:

  • src/fullDebug/ (nhóm tài nguyên biến thể bản dựng)
  • src/debug/ (nhóm tài nguyên loại bản dựng)
  • src/full/ (nhóm tài nguyên phiên bản sản phẩm)
  • src/main/ (nhóm tài nguyên chính)

Lưu ý: Khi tạo một tệp hoặc thư mục mới trong Android Studio, hãy sử dụng các lựa chọn trong trình đơn File > New (Tệp > Mới) để tạo tệp hoặc thư mục cho một nhóm tài nguyên. Các nhóm tài nguyên mà bạn có thể chọn là tuỳ thuộc vào cấu hình bản dựng và Android Studio sẽ tự động tạo những thư mục cần thiết nếu chưa có.

Nếu các nhóm tài nguyên chứa nhiều phiên bản của cùng một tệp thì Gradle sẽ áp dụng thứ tự ưu tiên dưới đây để quyết định tệp sẽ được sử dụng (nhóm tài nguyên ở bên trái ghi đè các tệp và chế độ cài đặt của nhóm tài nguyên ở bên phải):

biến thể bản dựng > loại bản dựng > phiên bản sản phẩm > nhóm tài nguyên chính > phần phụ thuộc thư viện

Khi áp dụng thứ tự này, Gradle có thể vừa sử dụng các tệp dành riêng cho biến thể bản dựng bạn đang cố gắng tạo, vừa dùng lại những hoạt động, logic ứng dụng và tài nguyên mà các phiên bản khác của ứng dụng cũng sử dụng.

Khi hợp nhất nhiều tệp kê khai, Gradle cũng áp dụng thứ tự ưu tiên này. Vì vậy, mỗi biến thể bản dựng có thể xác định những thành phần hoặc quyền riêng trong tệp kê khai hoàn thiện. Để tìm hiểu thêm về cách tạo nhóm tài nguyên tuỳ chỉnh, hãy đọc phần Tạo nhóm tài nguyên.

Các hệ thống xây dựng khác

Bạn có thể xây dựng ứng dụng Android bằng Bazel nhưng hiện việc này vẫn chưa được hỗ trợ chính thức. Android Studio chưa chính thức hỗ trợ các dự án Bazel.

Để hiểu rõ hơn về những hạn chế hiện tại đối với việc xây dựng ứng dụng bằng Bazel, hãy xem các vấn đề đã biết.