Dependencies
Dependencies là các thư viện bên ngoài mà ứng dụng của bạn sử dụng. Gradle giúp quản lý việc tải, cập nhật và tích hợp các thư viện này một cách tự động.
Dependency là gì?
Phần tiêu đề “Dependency là gì?”Khi phát triển Android app, bạn sử dụng nhiều thư viện:
- AndroidX libraries - Core Android components
- Jetpack Compose - UI framework
- Retrofit - Networking
- Room - Database
- Hilt/Koin - Dependency Injection
Gradle tự động:
- Tải thư viện từ repositories (Maven Central, Google)
- Tải các transitive dependencies (dependencies của dependency)
- Resolve conflicts giữa các versions
Dependency Configurations
Phần tiêu đề “Dependency Configurations”Configuration xác định khi nào và như thế nào dependency được sử dụng:
dependencies { implementation(libs.retrofit) // Compile + Runtime api(libs.retrofit) // Compile + Runtime (exported) compileOnly(libs.lombok) // Compile only runtimeOnly(libs.jdbc.driver) // Runtime only
testImplementation(libs.junit) // Unit tests androidTestImplementation(libs.espresso)// Instrumented tests
ksp(libs.room.compiler) // Annotation processing
debugImplementation(libs.leakcanary) // Debug build only}Chi tiết các configurations
Phần tiêu đề “Chi tiết các configurations”| Configuration | Compile Classpath | Runtime Classpath | Exported | Use Case |
|---|---|---|---|---|
implementation |
✅ | ✅ | ❌ | Thư viện internal |
api |
✅ | ✅ | ✅ | Thư viện cần expose |
compileOnly |
✅ | ❌ | ❌ | Compile-time only |
runtimeOnly |
❌ | ✅ | ❌ | Runtime plugins |
testImplementation |
✅ (tests) | ✅ (tests) | ❌ | Unit tests |
androidTestImplementation |
✅ (Android tests) | ✅ (Android tests) | ❌ | Instrumented tests |
implementation vs api
Phần tiêu đề “implementation vs api”flowchart LR subgraph "implementation" A1[":app"] --> B1[":feature"] B1 --> C1["Retrofit"] A1 -.->|"❌ Cannot access"| C1 end
subgraph "api" A2[":app"] --> B2[":core:network"] B2 --> C2["Retrofit"] A2 -->|"✅ Can access"| C2 end
style C1 fill:#ffcdd2 style C2 fill:#c8e6c9implementation (Khuyến nghị)
Phần tiêu đề “implementation (Khuyến nghị)”Dependency chỉ visible trong module hiện tại:
dependencies { implementation(libs.retrofit) // Retrofit chỉ visible trong :feature:home}:app → :feature:home → Retrofit ❌ Không thể access Retrofit từ :appƯu điểm:
- Build nhanh hơn (incremental)
- Khi
libs.retrofitthay đổi, chỉ rebuild:feature:home - Encapsulation tốt hơn
Dependency được export cho modules phụ thuộc:
dependencies { api(libs.retrofit) // Retrofit visible cho tất cả modules dùng :core:network}:app → :core:network → Retrofit ✅ :app có thể access RetrofitKhi nào dùng api:
- Khi public interface của module expose types từ dependency
- Ví dụ:
fun createRetrofitService(): Retrofit
⚠️ Quan trọng: Ưu tiên dùng
implementationtrừ khi cần expose types. Quá nhiềuapilàm chậm build.
Annotation Processors
Phần tiêu đề “Annotation Processors”Các thư viện code generation sử dụng annotation processors:
KSP (Kotlin Symbol Processing) - Khuyến nghị
Phần tiêu đề “KSP (Kotlin Symbol Processing) - Khuyến nghị”plugins { alias(libs.plugins.ksp)}
dependencies { implementation(libs.room.runtime) implementation(libs.room.ktx) ksp(libs.room.compiler) // KSP processor
implementation(libs.hilt.android) ksp(libs.hilt.compiler)}KAPT (Kotlin Annotation Processing Tool) - Legacy
Phần tiêu đề “KAPT (Kotlin Annotation Processing Tool) - Legacy”plugins { id("org.jetbrains.kotlin.kapt")}
dependencies { implementation(libs.hilt.android) kapt(libs.hilt.compiler) // KAPT processor}So sánh KSP vs KAPT
Phần tiêu đề “So sánh KSP vs KAPT”| KSP | KAPT | |
|---|---|---|
| Tốc độ | ⚡ Nhanh (2x) | 🐢 Chậm |
| Kotlin-native | ✅ Có | ❌ Wraps javac |
| Recommended | ✅ Có | ⚠️ Chỉ khi thư viện chưa hỗ trợ KSP |
💡 Mẹo: Xem Migrate from KAPT to KSP để chuyển đổi.
Variant-specific Dependencies
Phần tiêu đề “Variant-specific Dependencies”Thêm dependencies cho build variant cụ thể:
dependencies { // Debug only debugImplementation(libs.leakcanary) debugImplementation(libs.compose.ui.tooling)
// Release only releaseImplementation(libs.firebase.crashlytics)
// Flavor specific demoImplementation(libs.demo.mode.library) fullImplementation(libs.premium.features)
// Variant specific (flavor + build type) devDebugImplementation(libs.mock.server)}Module Dependencies
Phần tiêu đề “Module Dependencies”Thêm dependency vào module khác trong cùng project:
dependencies { implementation(project(":core:network")) implementation(project(":core:database")) implementation(project(":feature:home")) implementation(project(":feature:profile"))}
// :feature:home/build.gradle.ktsdependencies { implementation(project(":core:network")) implementation(project(":core:common"))}Platform (BOM) Dependencies
Phần tiêu đề “Platform (BOM) Dependencies”Bill of Materials (BOM) quản lý versions của một họ thư viện:
dependencies { // Import Compose BOM implementation(platform(libs.androidx.compose.bom))
// Compose libraries - KHÔNG cần version implementation(libs.androidx.ui) implementation(libs.androidx.ui.graphics) implementation(libs.androidx.material3)
// Import Firebase BOM implementation(platform(libs.firebase.bom))
// Firebase libraries - KHÔNG cần version implementation(libs.firebase.analytics) implementation(libs.firebase.crashlytics)}📝 Lưu ý: BOM đảm bảo các thư viện trong cùng một họ có versions compatible với nhau.
Dependencies phổ biến
Phần tiêu đề “Dependencies phổ biến”Jetpack Compose
Phần tiêu đề “Jetpack Compose”[versions]compose-bom = "2024.11.00"activity-compose = "1.9.3"
[libraries]androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }androidx-ui = { group = "androidx.compose.ui", name = "ui" }androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }androidx-material3 = { group = "androidx.compose.material3", name = "material3" }androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity-compose" }dependencies { implementation(platform(libs.androidx.compose.bom)) implementation(libs.androidx.ui) implementation(libs.androidx.ui.graphics) implementation(libs.androidx.material3) implementation(libs.androidx.activity.compose)
debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.tooling.preview)}Room Database
Phần tiêu đề “Room Database”[versions]room = "2.6.1"
[libraries]room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
[plugins]room = { id = "androidx.room", version.ref = "room" }plugins { alias(libs.plugins.room) alias(libs.plugins.ksp)}
room { schemaDirectory("$projectDir/schemas")}
dependencies { implementation(libs.room.runtime) implementation(libs.room.ktx) ksp(libs.room.compiler)}Retrofit
Phần tiêu đề “Retrofit”[versions]retrofit = "2.11.0"okhttp = "4.12.0"
[libraries]retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }retrofit-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }retrofit-kotlinx-serialization = { module = "com.squareup.retrofit2:converter-kotlinx-serialization", version.ref = "retrofit" }okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
[bundles]retrofit = ["retrofit", "retrofit-gson", "okhttp-logging"]dependencies { implementation(libs.bundles.retrofit) // hoặc implementation(libs.retrofit) implementation(libs.retrofit.gson) implementation(libs.okhttp.logging)}Hilt (Dependency Injection)
Phần tiêu đề “Hilt (Dependency Injection)”[versions]hilt = "2.52"hilt-navigation-compose = "1.2.0"
[libraries]hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hilt-navigation-compose" }
[plugins]hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }plugins { alias(libs.plugins.hilt) alias(libs.plugins.ksp)}
dependencies { implementation(libs.hilt.android) implementation(libs.hilt.navigation.compose) ksp(libs.hilt.compiler)}Navigation Compose
Phần tiêu đề “Navigation Compose”[versions]navigation = "2.8.4"kotlinx-serialization = "1.7.3"
[libraries]navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" }kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
[plugins]kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }plugins { alias(libs.plugins.kotlin.serialization)}
dependencies { implementation(libs.navigation.compose) implementation(libs.kotlinx.serialization.json)}Coil (Image Loading)
Phần tiêu đề “Coil (Image Loading)”[versions]coil = "2.7.0"
[libraries]coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }coil-gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" }coil-svg = { module = "io.coil-kt:coil-svg", version.ref = "coil" }dependencies { implementation(libs.coil.compose)}Xem Dependencies
Phần tiêu đề “Xem Dependencies”Dependency Tree
Phần tiêu đề “Dependency Tree”# Xem tất cả dependencies của module :app./gradlew :app:dependencies
# Xem configuration cụ thể./gradlew :app:dependencies --configuration releaseRuntimeClasspath
# Tìm dependency cụ thể./gradlew :app:dependencyInsight --dependency retrofitDependency Updates
Phần tiêu đề “Dependency Updates”Sử dụng Gradle Versions Plugin để kiểm tra updates:
plugins { id("com.github.ben-manes.versions") version "0.51.0"}./gradlew dependencyUpdatesBest Practices
Phần tiêu đề “Best Practices”1. Sử dụng Version Catalog
Phần tiêu đề “1. Sử dụng Version Catalog”// ✅ Tốtimplementation(libs.retrofit)
// ❌ Tránhimplementation("com.squareup.retrofit2:retrofit:2.11.0")2. Ưu tiên implementation
Phần tiêu đề “2. Ưu tiên implementation”// ✅ Mặc định dùng implementationimplementation(libs.retrofit)
// ⚠️ Chỉ dùng api khi cần export typesapi(libs.retrofit)3. Sử dụng KSP thay KAPT
Phần tiêu đề “3. Sử dụng KSP thay KAPT”// ✅ Khuyến nghịksp(libs.room.compiler)
// ⚠️ Legacy - chỉ khi thư viện chưa hỗ trợ KSPkapt(libs.room.compiler)4. Tránh dynamic versions
Phần tiêu đề “4. Tránh dynamic versions”// ❌ Nguy hiểm - có thể break build bất ngờimplementation("com.example:library:1.+")implementation("com.example:library:latest.release")
// ✅ Explicit versionimplementation("com.example:library:1.2.3")5. Sử dụng BOM khi có thể
Phần tiêu đề “5. Sử dụng BOM khi có thể”// ✅ BOM quản lý compatible versionsimplementation(platform(libs.androidx.compose.bom))implementation(libs.androidx.ui)implementation(libs.androidx.material3)Tóm tắt
Phần tiêu đề “Tóm tắt”| Concept | Mô tả |
|---|---|
implementation |
Dependency internal, không export |
api |
Dependency được export cho dependent modules |
compileOnly |
Chỉ compile-time |
runtimeOnly |
Chỉ runtime |
ksp |
Kotlin Symbol Processing (annotation processor) |
testImplementation |
Dependencies cho unit tests |
debugImplementation |
Dependencies cho debug builds |
platform() |
Import BOM để quản lý versions |
project() |
Depend vào module khác trong project |