依赖注入(Dependency Injection, DI) 是一种设计模式,用于实现对象与其依赖项之间的解耦。在 Android 开发中,依赖注入可以帮助我们更高效地管理组件的生命周期、测试以及代码的可维护性。Hilt 是 Google 推出的一个基于 Dagger 的依赖注入库,专门为 Android 优化,简化了依赖注入的配置和使用。本章节将介绍依赖注入的基本概念、Hilt 的使用、Hilt 与 Jetpack 组件的集成以及实战案例。
13.1 依赖注入简介
-
什么是依赖注入:
- 依赖注入是一种设计模式,用于实现对象与其依赖项之间的解耦。
- 通过依赖注入,类不再负责创建其依赖项,而是由外部注入依赖项。
-
依赖注入的优势:
- 解耦: 类与其依赖项解耦,提高代码的可维护性和可测试性。
- 可测试性: 更容易编写单元测试,可以通过注入不同的依赖项来模拟不同的行为。
- 可复用性: 依赖项可以在不同的类之间复用,减少代码重复。
- 生命周期管理: 依赖项的生命周期可以由依赖注入框架管理,避免内存泄漏。
13.2 Hilt 简介
Hilt 是 Google 推出的一个基于 Dagger 的依赖注入库,专门为 Android 优化。Hilt 简化了 Dagger 的配置和使用,提供了与 Android Jetpack 组件的无缝集成。
- Hilt 的优势:
- 简化配置: Hilt 提供了预定义的组件和作用域,减少了 Dagger 的样板代码。
- 与 Jetpack 集成: Hilt 与 Android Jetpack 组件(如 ViewModel, LiveData, Room 等)无缝集成。
- 自动生成代码: Hilt 会自动生成 Dagger 组件和模块,减少手动配置的工作量。
- 易于使用: Hilt 提供了简单的 API,易于上手和使用。
13.3 Hilt 的基本使用
13.3.1 添加 Hilt 依赖
在 build.gradle
文件中添加 Hilt 依赖:
// 项目级 build.gradle
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.44"
}
// 应用级 build.gradle
plugins {
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
...
}
dependencies {
implementation "com.google.dagger:hilt-android:2.44"
kapt "com.google.dagger:hilt-compiler:2.44"
}
13.3.2 初始化 Hilt
在 Application
类上使用 @HiltAndroidApp
注解,初始化 Hilt:
@HiltAndroidApp
class MyApplication : Application()
在 AndroidManifest.xml
中注册 Application
类:
<application
android:name=".MyApplication"
... >
...
</application>
13.3.3 使用 Hilt 注入依赖
-
创建模块:
- 使用
@Module
和@InstallIn
注解创建模块,定义依赖项。
@Module @InstallIn(SingletonComponent::class) object AppModule { @Provides @Singleton fun provideUserRepository(): UserRepository { return UserRepository() } @Provides @Singleton fun provideApiService(): ApiService { return Retrofit.Builder() .baseUrl("https://api.example.com") .build() .create(ApiService::class.java) } }
- 使用
-
注入依赖:
- 使用
@Inject
注解注入依赖。
@AndroidEntryPoint class MyActivity : AppCompatActivity() { @Inject lateinit var userRepository: UserRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 使用 userRepository } }
- 使用
-
注入 ViewModel:
- 使用
@HiltViewModel
注解创建 ViewModel,并使用@Inject
注入依赖。
@HiltViewModel class MyViewModel @Inject constructor( private val userRepository: UserRepository ) : ViewModel() { // ViewModel 代码 }
@AndroidEntryPoint class MyActivity : AppCompatActivity() { private val viewModel: MyViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 使用 viewModel } }
- 使用
13.4 Hilt 与 Jetpack 组件的集成
Hilt 与 Jetpack 组件(如 ViewModel, LiveData, Room 等)无缝集成,可以更方便地管理组件的生命周期和依赖关系。
-
ViewModel:
- 使用
@HiltViewModel
注解创建 ViewModel,并注入依赖。
@HiltViewModel class MyViewModel @Inject constructor( private val userRepository: UserRepository ) : ViewModel() { // ViewModel 代码 }
- 使用
-
LiveData:
- Hilt 可以注入 ViewModel 所需的 LiveData。
@HiltViewModel class MyViewModel @Inject constructor( private val userRepository: UserRepository ) : ViewModel() { val users: LiveData<List<User>> = userRepository.getUsers() }
-
Room:
- Hilt 可以注入 Room 数据库和 DAO。
@Module @InstallIn(SingletonComponent::class) object DatabaseModule { @Provides @Singleton fun provideDatabase(@ApplicationContext context: Context): AppDatabase { return Room.databaseBuilder( context, AppDatabase::class.java, "database-name" ).build() } @Provides fun provideUserDao(database: AppDatabase): UserDao { return database.userDao() } }
13.5 实战案例
-
案例一:使用 Hilt 实现用户列表应用
- 创建一个 ViewModel,使用 Hilt 注入 UserRepository。
- 在 Activity 中观察 ViewModel 的 LiveData,更新 RecyclerView。
@HiltViewModel class UserViewModel @Inject constructor( private val userRepository: UserRepository ) : ViewModel() { val users: LiveData<List<User>> = userRepository.getUsers() } @AndroidEntryPoint class UserActivity : AppCompatActivity() { private val viewModel: UserViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user) viewModel.users.observe(this) { users -> // 更新 UI val recyclerView = findViewById<RecyclerView>(R.id.recyclerView) recyclerView.adapter = UserAdapter(users) } viewModel.loadUsers() } }
-
案例二:使用 Hilt 实现图片浏览应用
- 创建一个 ViewModel,使用 Hilt 注入 ApiService。
- 在 Jetpack Compose Composable 中观察 ViewModel 的 Flow,更新 UI。
@HiltViewModel class ImageViewModel @Inject constructor( private val apiService: ApiService ) : ViewModel() { val images: Flow<List<Image>> = apiService.fetchImages() } @Composable fun ImageScreen(viewModel: ImageViewModel) { val images by viewModel.images.collectAsState(initial = emptyList()) LazyColumn { items(images) { image -> Image( painter = painterResource(id = image.resId), contentDescription = image.description ) } } }
13.6 课后作业
-
任务一:使用 Hilt 实现用户列表应用
- 创建一个 ViewModel,使用 Hilt 注入 UserRepository。
- 在 Activity 中观察 ViewModel 的 LiveData,更新 RecyclerView。
-
任务二:使用 Hilt 实现图片浏览应用
- 创建一个 ViewModel,使用 Hilt 注入 ApiService。
- 在 Jetpack Compose Composable 中观察 ViewModel 的 Flow,更新 UI。
-
任务三:使用 Hilt 实现网络请求
- 创建一个 ViewModel,使用 Hilt 注入 ApiService。
- 在 Activity 中使用协程进行网络请求,并更新 UI。
通过本章节的学习,学员将能够掌握 Hilt 依赖注入的基本概念、使用方法以及与 Jetpack 组件的集成,并能够使用 Hilt 简化依赖管理,提高代码的可维护性和可测试性。