Dependencies trong Android
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ì?
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
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
| 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
implementation (Khuyến nghị)
Dependency chỉ visible trong module hiện tại:
// :feature:home/build.gradle.kts
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
api
Dependency được export cho modules phụ thuộc:
// :core:network/build.gradle.kts
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
Các thư viện code generation sử dụng annotation processors:
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
plugins {
id("org.jetbrains.kotlin.kapt")
}
dependencies {
implementation(libs.hilt.android)
kapt(libs.hilt.compiler) // KAPT processor
}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
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
Thêm dependency vào module khác trong cùng project:
// :app/build.gradle.kts
dependencies {
implementation(project(":core:network"))
implementation(project(":core:database"))
implementation(project(":feature:home"))
implementation(project(":feature:profile"))
}
// :feature:home/build.gradle.kts
dependencies {
implementation(project(":core:network"))
implementation(project(":core:common"))
}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
Jetpack Compose
# libs.versions.toml
[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
[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
[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)
[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
[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)
[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
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
Sử dụng Gradle Versions Plugin để kiểm tra updates:
// settings.gradle.kts
plugins {
id("com.github.ben-manes.versions") version "0.51.0"
}./gradlew dependencyUpdatesBest Practices
1. Sử dụng Version Catalog
// ✅ Tốt
implementation(libs.retrofit)
// ❌ Tránh
implementation("com.squareup.retrofit2:retrofit:2.11.0")2. Ưu tiên implementation
// ✅ Mặc định dùng implementation
implementation(libs.retrofit)
// ⚠️ Chỉ dùng api khi cần export types
api(libs.retrofit)3. Sử dụng KSP thay KAPT
// ✅ Khuyến nghị
ksp(libs.room.compiler)
// ⚠️ Legacy - chỉ khi thư viện chưa hỗ trợ KSP
kapt(libs.room.compiler)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 version
implementation("com.example:library:1.2.3")5. Sử dụng BOM khi có thể
// ✅ BOM quản lý compatible versions
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.material3)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 |