Thêm phần phụ thuộc của bản dựng

Hệ thống xây dựng Gradle trong Android Studio cho phép bạn đưa các tệp nhị phân bên ngoài hoặc các mô-đun thư viện khác vào bản dựng dưới dạng các phần phụ thuộc. Các phần phụ thuộc có thể nằm trên máy hoặc trong một kho lưu trữ từ xa, đồng thời các phần phụ thuộc bắc cầu mà các phần phụ thuộc đó khai báo cũng tự động được đưa vào. Trang này mô tả cách sử dụng các phần phụ thuộc với dự án Android, gồm có thông tin chi tiết về các hành vi và cấu hình dành riêng cho trình bổ trợ Android cho Gradle (AGP). Để được hướng dẫn khái niệm chuyên sâu hơn về phần phụ thuộc Gradle, bạn cũng nên xem Hướng dẫn quản lý phần phụ thuộc Gradle nhưng hãy nhớ rằng dự án Android của bạn chỉ được sử dụng các Cấu hình phần phụ thuộc được xác định trên trang này.

Thêm phần phụ thuộc trình bổ trợ hoặc thư viện

Cách tốt nhất để thêm và quản lý các phần phụ thuộc của bản dựng là sử dụng danh mục phiên bản, phương thức mà các dự án mới sử dụng theo mặc định. Phần này trình bày các loại cấu hình phổ biến nhất được dùng cho các dự án Android; hãy tham khảo tài liệu về Gradle để biết thêm các tuỳ chọn. Để xem ví dụ về một ứng dụng sử dụng danh mục phiên bản, hãy xem Now in Android. Nếu bạn đã thiết lập các phần phụ thuộc bản dựng mà không có danh mục phiên bản và có một dự án nhiều mô-đun, bạn nên di chuyển.

Để biết hướng dẫn về cách thêm và quản lý các phần phụ thuộc gốc (không phổ biến), hãy xem bài viết Các phần phụ thuộc gốc.

Trong ví dụ sau, chúng ta thêm phần phụ thuộc nhị phân từ xa (thư viện Macrobenchmark của Jetpack), phần phụ thuộc mô-đun thư viện cục bộ (myLibrary) và phần phụ thuộc trình bổ trợ (trình bổ trợ Android cho Gradle) vào dự án. Dưới đây là các bước chung để thêm các phần phụ thuộc này vào dự án:

  1. Thêm bí danh cho phiên bản phần phụ thuộc mà bạn muốn trong phần [versions] của tệp danh mục phiên bản, có tên là libs.versions.toml (trong thư mục gradle trong chế độ xem Dự án hoặc Tập lệnh Gradle trong chế độ xem Android):

    [versions]
    agp = "8.3.0"
    androidx-macro-benchmark = "1.2.2"
    my-library = "1.4"
    
    [libraries]
    ...
    
    [plugins]
    ...
    

    Bí danh có thể chứa dấu gạch ngang hoặc dấu gạch dưới. Các bí danh này tạo ra các giá trị lồng nhau mà bạn có thể tham chiếu trong tập lệnh bản dựng. Các tệp tham chiếu bắt đầu bằng tên của danh mục, phần libs của libs.versions.toml. Khi sử dụng một danh mục phiên bản, bạn nên giữ nguyên giá trị mặc định là "libs".

  2. Thêm bí danh cho phần phụ thuộc trong phần [libraries] (đối với các tệp nhị phân từ xa hoặc mô-đun thư viện cục bộ) hoặc [plugins] (đối với các trình bổ trợ) của tệp libs.versions.toml.

    [versions]
    ...
    
    [libraries]
    androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidx-macro-benchmark" }
    my-library = { group = "com.myapplication", name = "mylibrary", version.ref = "my-library" }
    
    [plugins]
    androidApplication = { id = "com.android.application", version.ref = "agp" }
    

    Một số thư viện có trong Bảng kê khai thành phần (BOM) đã xuất bản, trong đó nhóm các gia đình thư viện và phiên bản của các thư viện đó. Bạn có thể đưa Bảng kê khai thành phần vào danh mục phiên bản và tệp bản dựng, đồng thời để bảng kê khai này quản lý các phiên bản đó cho bạn. Vui lòng xem bài viết Sử dụng Bảng kê khai thành phần để biết thông tin chi tiết.

  3. Thêm tệp tham chiếu đến bí danh phần phụ thuộc vào tập lệnh bản dựng của (các) mô-đun yêu cầu phần phụ thuộc đó. Chuyển đổi dấu gạch dưới và dấu gạch ngang của bí danh thành dấu chấm khi bạn tham chiếu bí danh đó từ tập lệnh bản dựng. Tập lệnh bản dựng cấp mô-đun của chúng ta sẽ có dạng như sau:

    Kotlin

    plugins {
      alias(libs.plugins.androidApplication)
    }
    
    dependencies {
      implementation(libs.androidx.benchmark.macro)
      implementation(libs.my.library)
    }

    Groovy

    plugins {
      alias 'libs.plugins.androidApplication'
    }
    
    dependencies {
      implementation libs.androidx.benchmark.macro
      implementation libs.my.library
    }

    Tệp tham chiếu trình bổ trợ bao gồm plugins sau tên danh mục, còn tệp tham chiếu phiên bản bao gồm versions sau tên danh mục (thông tin tham chiếu phiên bản không phổ biến; hãy xem phần Các phần phụ thuộc có cùng số phiên bản để biết ví dụ về tệp tham chiếu phiên bản.) Tham chiếu thư viện không bao gồm bộ hạn định libraries, vì vậy, bạn không thể sử dụng versions hoặc plugins ở đầu bí danh thư viện.

Định cấu hình phần phụ thuộc

Bên trong khối dependencies, bạn có thể khai báo phần phụ thuộc thư viện bằng cách sử dụng một trong nhiều cấu hình phần phụ thuộc (chẳng hạn như implementation hiển thị trước đó). Mỗi cấu hình phần phụ thuộc cung cấp cho Gradle các hướng dẫn khác nhau về cách sử dụng phần phụ thuộc. Bảng sau đây mô tả từng cấu hình phần phụ thuộc có thể sử dụng trong dự án Android.

Cấu hình Hành vi
implementation Gradle thêm phần phụ thuộc vào classpath biên dịch và đóng gói phần phụ thuộc đó vào đầu ra của bản dựng. Khi định cấu hình một phần phụ thuộc implementation, mô-đun sẽ cho Gradle biết rằng bạn không muốn mô-đun này làm rò rỉ phần phụ thuộc đó ra các mô-đun khác tại thời điểm biên dịch. Điều này nghĩa là phần phụ thuộc không được cung cấp cho các mô-đun khác phụ thuộc vào mô-đun hiện tại.

Việc sử dụng cấu hình phần phụ thuộc này thay vì api có thể sẽ cải thiện đáng kể thời gian xây dựng vì cấu hình này làm giảm số lượng mô-đun mà hệ thống xây dựng cần biên dịch lại. Chẳng hạn, nếu một phần phụ thuộc implementation thay đổi API của mình thì Gradle sẽ chỉ biên dịch lại phần phụ thuộc đó cùng những mô-đun phụ thuộc trực tiếp. Hầu hết các mô-đun ứng dụng và mô-đun kiểm thử nên sử dụng cấu hình này.

api Gradle thêm phần phụ thuộc vào đường dẫn lớp biên dịch và đầu ra bản dựng. Khi một mô-đun có một phần phụ thuộc api, mô-đun đó sẽ cho Gradle biết rằng mô-đun đó muốn xuất chuyển tiếp phần phụ thuộc đó sang các mô-đun khác để có thể sử dụng trong cả thời gian chạy và thời gian biên dịch.

Hãy sử dụng cấu hình này một cách thận trọng và chỉ dùng với các phần phụ thuộc mà bạn cần xuất theo cách chuyển tiếp sang những đối tượng sử dụng khác ở cấp độ cao hơn. Nếu một phần phụ thuộc api thay đổi API bên ngoài, thì Gradle sẽ biên dịch lại tất cả các mô-đun có quyền truy cập vào phần phụ thuộc đó tại thời gian biên dịch. Việc có một số lượng lớn các phần phụ thuộc api có thể gia tăng đáng kể thời gian tạo bản dựng. Trừ phi bạn muốn hiển thị API của một phần phụ thuộc cho một mô-đun riêng, các mô-đun thư viện nên sử dụng các phần phụ thuộc implementation.

compileOnly Gradle chỉ thêm phần phụ thuộc vào đường dẫn lớp biên dịch (nghĩa là phần phụ thuộc này không được thêm vào đầu ra của bản dựng). Điều này rất hữu ích khi tạo một mô-đun Android và cần có phần phụ thuộc trong quá trình biên dịch, nhưng không bắt buộc phải thêm phần phụ thuộc này tại thời gian chạy. Ví dụ: nếu phụ thuộc vào một thư viện chỉ bao gồm các chú thích tại thời điểm biên dịch (thường dùng để tạo mã nhưng thường không có trong đầu ra của bản dựng), bạn có thể đánh dấu thư viện đó là compileOnly.

Nếu sử dụng cấu hình này, bạn phải đưa điều kiện thời gian chạy vào mô-đun thư viện để kiểm tra xem phần phụ thuộc có sẵn hay không, sau đó thay đổi linh hoạt hành vi của mô-đun để vẫn có thể hoạt động nếu như phần phụ thuộc không được cung cấp. Điều này giúp giảm kích thước của ứng dụng cuối cùng bằng cách không thêm các phần phụ thuộc bắc cầu không quan trọng.

Lưu ý: Bạn không thể dùng cấu hình compileOnly với các phần phụ thuộc Android Archive (AAR).

runtimeOnly Gradle chỉ thêm phần phụ thuộc vào đầu ra của bản dựng, để sử dụng trong thời gian chạy. Điều đó có nghĩa là phần phụ thuộc này sẽ không được thêm vào đường dẫn lớp biên dịch. Phương thức này hiếm khi được sử dụng trên Android, nhưng thường được dùng trong các ứng dụng máy chủ để cung cấp cách triển khai ghi nhật ký. Ví dụ: một thư viện có thể sử dụng API ghi nhật ký không bao gồm hoạt động triển khai. Người dùng thư viện đó có thể thêm thư viện đó làm phần phụ thuộc implementation và đưa vào phần phụ thuộc runtimeOnly để triển khai tính năng ghi nhật ký thực tế.
ksp
kapt
annotationProcessor

Các cấu hình này cung cấp các thư viện xử lý chú thích và các ký hiệu khác trong mã trước khi mã được biên dịch. Các công cụ này thường xác thực mã của bạn hoặc tạo mã bổ sung, giúp giảm lượng mã bạn cần viết.

Để thêm một phần phụ thuộc như vậy, bạn phải thêm phần phụ thuộc đó vào đường dẫn lớp xử lý chú thích bằng cách sử dụng cấu hình ksp, kapt hoặc annotationProcessor. Việc sử dụng các cấu hình này giúp cải thiện hiệu suất của bản dựng bằng cách tách đường dẫn lớp biên dịch khỏi đường dẫn lớp trình xử lý chú giải. Nếu tìm thấy trình xử lý chú giải trên classpath biên dịch, Gradle sẽ vô hiệu hoá tính năng miễn trừ biên dịch (compile avoidance) vì tính năng này sẽ tác động tiêu cực đến thời gian xây dựng (Gradle phiên bản 5.0 trở lên sẽ bỏ qua các trình xử lý chú giải trên classpath biên dịch).

Trình bổ trợ Android cho Gradle giả định một phần phụ thuộc là trình xử lý chú thích nếu tệp JAR của phần phụ thuộc đó có chứa tệp sau:

META-INF/services/javax.annotation.processing.Processor

Nếu trình bổ trợ phát hiện một trình xử lý chú thích trên đường dẫn lớp biên dịch, một lỗi bản dựng sẽ xảy ra.

ksp là một Trình xử lý biểu tượng Kotlin và được chạy bằng trình biên dịch Kotlin.

kaptapt là các công cụ riêng biệt giúp xử lý chú giải trước khi trình biên dịch Kotlin hoặc Java thực thi.

Khi quyết định sử dụng cấu hình nào, hãy cân nhắc những yếu tố sau:

  • Nếu có một trình xử lý dưới dạng Trình xử lý ký hiệu Kotlin, hãy sử dụng trình xử lý đó làm phần phụ thuộc ksp. Hãy xem phần Di chuyển từ kapt sang ksp để biết thông tin chi tiết về cách sử dụng Trình xử lý biểu tượng Kotlin.
  • Nếu trình xử lý không có sẵn dưới dạng Trình xử lý biểu tượng Kotlin:
    • Nếu dự án của bạn bao gồm nguồn Kotlin (nhưng cũng có thể bao gồm nguồn Java), hãy sử dụng kapt để đưa nguồn đó vào.
    • Nếu dự án của bạn chỉ sử dụng nguồn Java, hãy dùng annotationProcessor để thêm nguồn đó.

Để biết thêm thông tin về cách sử dụng trình xử lý chú giải, hãy xem nội dung Thêm trình xử lý chú giải.

lintChecks

Sử dụng cấu hình này để đưa một thư viện chứa các phần kiểm tra tìm lỗi mã nguồn vào để Gradle thực thi khi tạo dự án ứng dụng Android.

Xin lưu ý rằng các AAR chứa tệp lint.jar sẽ tự động chạy các quy trình kiểm tra được xác định trong tệp lint.jar đó; bạn không cần thêm phần phụ thuộc lintChecks rõ ràng. Nhờ đó, bạn có thể xác định các thư viện và yêu cầu kiểm tra tìm lỗi mã nguồn được liên kết trong một phần phụ thuộc, đảm bảo các bước kiểm tra đó sẽ được chạy khi người tiêu dùng sử dụng thư viện của bạn.

lintPublish Sử dụng cấu hình này trong các dự án thư viện Android để đưa các phần kiểm tra tìm lỗi mã nguồn mà bạn muốn Gradle biên dịch vào một tệp lint.jar và gói trong AAR của bạn. Điều này khiến các dự án sử dụng AAR của bạn cũng áp dụng phần kiểm tra lỗi mã nguồn đó. Nếu trước đó bạn đã sử dụng cấu hình phần phụ thuộc lintChecks để đưa các phần kiểm tra tìm lỗi mã nguồn vào trong AAR đã phát hành, thì bạn cần di chuyển các phần phụ thuộc đó để sử dụng cấu hình lintPublish.

Kotlin

dependencies {
  // Executes lint checks from the ":checks" project at build time.
  lintChecks(project(":checks"))
  // Compiles lint checks from the ":checks-to-publish" into a
  // lint.jar file and publishes it to your Android library.
  lintPublish(project(":checks-to-publish"))
}

Groovy

dependencies {
  // Executes lint checks from the ':checks' project at build time.
  lintChecks project(':checks')
  // Compiles lint checks from the ':checks-to-publish' into a
  // lint.jar file and publishes it to your Android library.
  lintPublish project(':checks-to-publish')
}

Định cấu hình phần phụ thuộc cho một biến thể bản dựng cụ thể

Tất cả các cấu hình trước đó đều áp dụng các phần phụ thuộc cho tất cả biến thể bản dựng. Thay vào đó, nếu bạn chỉ muốn khai báo một phần phụ thuộc dành riêng cho một nhóm tài nguyên biến thể bản dựng cụ thể hoặc dành cho một nhóm tài nguyên kiểm thử, bạn phải viết hoa tên cấu hình và thêm tiền tố là tên của biến thể bản dựng hoặc tên của nhóm tài nguyên kiểm thử.

Ví dụ: để chỉ thêm một phần phụ thuộc tệp nhị phân từ xa vào phiên bản sản phẩm "miễn phí" bằng cấu hình implementation, hãy sử dụng:

Kotlin

dependencies {
    freeImplementation("com.google.firebase:firebase-ads:21.5.1")
}

Groovy

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
}

Tuy nhiên, nếu muốn thêm phần phụ thuộc cho một biến thể kết hợp một phiên bản sản phẩm và một kiểu bản dựng, bạn phải khởi tạo tên cấu hình:

Kotlin

// Initializes a placeholder for the freeDebugImplementation dependency configuration.
val freeDebugImplementation by configurations.creating

dependencies {
    freeDebugImplementation(project(":free-support"))
}

Groovy

configurations {
    // Initializes a placeholder for the freeDebugImplementation dependency configuration.
    freeDebugImplementation {}
}

dependencies {
    freeDebugImplementation project(":free-support")
}

Để thêm các phần phụ thuộc implementation cho quy trình kiểm thử cục bộ và quy trình kiểm thử đo lường, bạn có thể xem đoạn mã sau:

Kotlin

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
}

Groovy

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
}

Tuy nhiên, một số cấu hình nhất định không có ý nghĩa trong trường hợp này. Chẳng hạn, vì các mô-đun khác không thể phụ thuộc vào androidTest, nên bạn sẽ nhận được cảnh báo sau nếu sử dụng cấu hình androidTestApi:

WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
'androidTestImplementation'.

Thứ tự phần phụ thuộc

Thứ tự liệt kê các phần phụ thuộc của bạn phản ánh rõ mức độ ưu tiên: thư viện đầu tiên có mức độ ưu tiên cao hơn thư viện thứ hai, thư viện thứ hai có mức độ ưu tiên cao hơn thư viện thứ ba, v.v. Thứ tự này rất quan trọng trong trường hợp tài nguyên được hợp nhất hoặc các phần tử tệp kê khai được hợp nhất vào trong ứng dụng từ thư viện.

Ví dụ: nếu dự án của bạn khai báo như sau:

  • Phần phụ thuộc trên LIB_ALIB_B (theo thứ tự đó)
  • LIB_A phụ thuộc vào LIB_CLIB_D (theo thứ tự đó)
  • LIB_B cũng phụ thuộc vào LIB_C

Khi đó, thứ tự phần phụ thuộc cố định sẽ như sau:

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

Điều này đảm bảo rằng cả LIB_ALIB_B đều có thể ghi đè LIB_C; và LIB_D vẫn sẽ có mức độ ưu tiên cao hơn LIB_BLIB_A (phụ thuộc vào LIB_D) có mức độ ưu tiên cao hơn LIB_B.

Để biết thêm thông tin về cách hợp nhất các tệp kê khai từ nhiều nguồn/phần phụ thuộc của các dự án khác nhau, hãy xem Hợp nhất nhiều tệp kê khai.

Thông tin phần phụ thuộc dành cho Play Console

Khi xây dựng ứng dụng, AGP sẽ bao gồm siêu dữ liệu mô tả các phần phụ thuộc thư viện được biên dịch thành ứng dụng. Khi bạn tải ứng dụng lên, Play Console sẽ kiểm tra siêu dữ liệu này để đưa ra cảnh báo về các vấn đề đã biết liên quan đến SDK và các phần phụ thuộc mà ứng dụng của bạn sử dụng. Trong một số trường hợp, Play Console sẽ đưa ra ý kiến phản hồi hữu ích để giải quyết các vấn đề đó.

Dữ liệu được một khoá ký Google Play nén, mã hoá và lưu trữ trong khối ký của ứng dụng phát hành. Bạn nên lưu giữ tệp phần phụ thuộc này để mang đến trải nghiệm an toàn và tích cực cho người dùng. Bạn có thể chọn không sử dụng bằng cách thêm khối dependenciesInfo sau đây vào tệp build.gradle.kts của mô-đun.

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

Để biết thêm thông tin về các chính sách cũng như vấn đề tiềm ẩn về phần phụ thuộc, hãy xem trang hỗ trợ của chúng tôi về Sử dụng SDK của bên thứ ba trong ứng dụng của bạn.

Thông tin chi tiết về SDK

Android Studio hiển thị các cảnh báo tìm lỗi mã nguồn trong tệp danh mục phiên bản và Hộp thoại cấu trúc dự án cho các SDK công khai trong Chỉ mục SDK của Google Play khi xảy ra các vấn đề sau:

  • Tác giả đánh dấu các SDK này là đã lỗi thời.
  • SDK vi phạm chính sách của Play.

Cảnh báo là tín hiệu cho biết bạn nên cập nhật các phần phụ thuộc đó, vì việc sử dụng các phiên bản lỗi thời có thể khiến bạn không thể phát hành ứng dụng lên Google Play Console trong tương lai.

Thêm phần phụ thuộc của bản dựng mà không cần danh mục phiên bản

Bạn nên sử dụng danh mục phiên bản để thêm và quản lý các phần phụ thuộc, nhưng các dự án đơn giản có thể không cần đến các danh mục này. Dưới đây là ví dụ về tệp bản dựng không sử dụng danh mục phiên bản:

Kotlin

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

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation("com.example.android:app-magic:12.3")
    // Dependency on a local library module
    implementation(project(":mylibrary"))
}

Groovy

plugins {
    id 'com.android.application'
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
    // Dependency on a local library module
    implementation project(':mylibrary')
}

Tệp bản dựng này khai báo một phần phụ thuộc trên phiên bản 12.3 của thư viện "app-magic", trong nhóm không gian tên "com.example.android". Nội dung khai báo phần phụ thuộc nhị phân từ xa là viết tắt của nội dung sau:

Kotlin

implementation(group = "com.example.android", name = "app-magic", version = "12.3")

Groovy

implementation group: 'com.example.android', name: 'app-magic', version: '12.3'

Tệp bản dựng cũng khai báo phần phụ thuộc trên một mô-đun thư viện Android có tên là "mylibrary"; tên này phải khớp với tên thư viện được khai báo bằng include: trong tệp settings.gradle.kts. Khi bạn tạo ứng dụng, hệ thống xây dựng sẽ biên dịch mô-đun thư viện và đóng gói nội dung kết quả biên dịch trong ứng dụng.

Tệp bản dựng cũng khai báo phần phụ thuộc trên trình bổ trợ Android cho Gradle (com.application.android). Nếu có nhiều mô-đun sử dụng cùng một trình bổ trợ, bạn chỉ có thể có một phiên bản trình bổ trợ trên đường dẫn lớp bản dựng trên tất cả các mô-đun. Thay vì chỉ định phiên bản trong mỗi tập lệnh bản dựng mô-đun, bạn nên đưa phần phụ thuộc trình bổ trợ vào tập lệnh bản dựng gốc cùng với phiên bản và cho biết không áp dụng phần phụ thuộc đó. Việc thêm apply false sẽ yêu cầu Gradle ghi lại phiên bản của trình bổ trợ nhưng không sử dụng trình bổ trợ đó trong bản dựng gốc. Thông thường, tập lệnh bản dựng gốc trống, ngoại trừ khối plugins này.

Kotlin

plugins {
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}

Groovy

plugins {
    id com.android.application version 8.3.0-rc02 apply false
}

Nếu có một dự án mô-đun duy nhất, bạn có thể chỉ định phiên bản một cách rõ ràng trong tập lệnh bản dựng cấp mô-đun và để trống tập lệnh bản dựng cấp dự án:

Kotlin

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

Groovy

plugins {
    id 'com.android.application' version '8.3.0-rc02'
}