通过SunFlower学习Hilt基本使用

文章目录

根据理解,使用SunFlower实例演示hilt基本使用。

添加hilt配置

  • 添加hilt gradle插件

    buildscript {
    dependencies {
    classpath "com.google.dagger:hilt-android-gradle-plugin:$hiltVersion"
    }
    }

  • 配置module使用插件进行注解处理

    apply plugin: 'kotlin-kapt'
    apply plugin: 'dagger.hilt.android.plugin'

  • 配置hilt依赖库版本

    dependencies {
    kapt "com.google.dagger:hilt-android-compiler:rootProject.hiltVersion" implementation "com.google.dagger:hilt-android:rootProject.hiltVersion"

  • App启用hilt

    @HiltAndroidApp
    class MainApplication : Application()

数据库自动注入

常规kotlin 规范创建AppDatabase、表、查询封装Dao

  • 创建数据库

    @Database(entities = [GardenPlanting::class, Plant::class], version = 1, exportSchema = false)
    @TypeConverters(Converters::class)
    abstract class AppDatabase : RoomDatabase() {
    abstract fun gardenPlantingDao(): GardenPlantingDao
    abstract fun plantDao(): PlantDao

    复制代码
      companion object {
    
          // For Singleton instantiation
          @Volatile private var instance: AppDatabase? = null
    
          fun getInstance(context: Context): AppDatabase {
              return instance ?: synchronized(this) {
                  instance ?: buildDatabase(context).also { instance = it }
              }
          }
    
          // Create and pre-populate the database. See this article for more details:
          // https://medium.com/google-developers/7-pro-tips-for-room-fbadea4bfbd1#4785
          private fun buildDatabase(context: Context): AppDatabase {
              return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
                  .addCallback(
                      object : RoomDatabase.Callback() {
                          override fun onCreate(db: SupportSQLiteDatabase) {
                              super.onCreate(db)
                              val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
                              WorkManager.getInstance(context).enqueue(request)
                          }
                      }
                  )
                  .build()
          }
      }

    }

  • 创建实体类

    @Entity(tableName = "plants")
    data class Plant(
    @PrimaryKey @ColumnInfo(name = "id") val plantId: String,
    val name: String,
    val description: String,
    val growZoneNumber: Int,
    val wateringInterval: Int = 7, // how often the plant should be watered, in days
    val imageUrl: String = ""
    ) {

    复制代码
      /**
       * Determines if the plant should be watered.  Returns true if [since]'s date > date of last
       * watering + watering Interval; false otherwise.
       */
      fun shouldBeWatered(since: Calendar, lastWateringDate: Calendar) =
          since > lastWateringDate.apply { add(DAY_OF_YEAR, wateringInterval) }
    
      override fun toString() = name

    }

  • 创建查询Dao

    @Dao
    interface PlantDao {
    @Query("SELECT * FROM plants ORDER BY name")
    fun getPlants(): Flow<List<Plant>>

    复制代码
      @Query("SELECT * FROM plants WHERE growZoneNumber = :growZoneNumber ORDER BY name")
      fun getPlantsWithGrowZoneNumber(growZoneNumber: Int): Flow<List<Plant>>
    
      @Query("SELECT * FROM plants WHERE id = :plantId")
      fun getPlant(plantId: String): Flow<Plant>
    
      @Insert(onConflict = OnConflictStrategy.REPLACE)
      suspend fun insertAll(plants: List<Plant>)

    }

创建DatabaseModule,向外提供数据库访问方法

数据库、PlantDao等不能直接添加@Inject注解构造函数,需要创建单独的module进行对外提供。

复制代码
@InstallIn(SingletonComponent::class)
@Module
class DatabaseModule {

    @Singleton
    @Provides
    fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase {
        return AppDatabase.getInstance(context)
    }

    @Provides
    fun providePlantDao(appDatabase: AppDatabase): PlantDao {
        return appDatabase.plantDao()
    }

@InstallIn和@Provider上Scope关系

@InstallIn指定module要注入的生成的component,@Provider函数可以添加Scoped限定符,但是必须与@InstallIn作用域一致。

@Provider函数添加Scoped限定符后,在component范围内仅仅创建一个实例。

Android 类 生成的组件 作用域
Application SingletonComponent @Singleton
Activity ActivityRetainedComponent @ActivityRetainedScoped
ViewModel ViewModelComponent @ViewModelScoped
Activity ActivityComponent @ActivityScoped
Fragment FragmentComponent @FragmentScoped

将模块安装到组件后,其绑定就可以用作该组件中其他绑定的依赖项,也可以用作组件层次结构中该组件下的任何子组件中绑定的依赖项。

这个函数直接向容器提供了AppDatabase、PlantDao对象。

PlantRepository 使用 PlantDao

复制代码
@Singleton
class PlantRepository @Inject constructor(private val plantDao: PlantDao) {

    fun getPlants() = plantDao.getPlants()

    fun getPlant(plantId: String) = plantDao.getPlant(plantId)

    fun getPlantsWithGrowZoneNumber(growZoneNumber: Int) =
        plantDao.getPlantsWithGrowZoneNumber(growZoneNumber)
}

@Singleton 这个和dagger2 @Module Provider方法限定符效果一样,标志在注入Component范围内单例。

@Inject 标志当component需要注入PlantRepository对象时,可以直接调用该函数进行获取。

@Inject constructor 参数plantDao,标志component使用PlantRepository对象时,需要提供的对象。

ViewModel使用PlantRepository

@HiltViewModel标志ViewModel自动进行构造函数注入

且必须存在@Inject修饰的构造函数

复制代码
@HiltViewModel
class PlantDetailViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle,
    plantRepository: PlantRepository,
    private val gardenPlantingRepository: GardenPlantingRepository,
) : ViewModel() {

    val plantId: String = savedStateHandle.get<String>(PLANT_ID_SAVED_STATE_KEY)!!

Fragment声明需要进行注入

@AndroidEntryPoint标志注入入口点

@AndroidEntryPoint 标志,当前Activity、Fragment需要进行hilt注入。
注:Fragment添加后,其所在的Activity同样必须添加

复制代码
@AndroidEntryPoint
class GardenActivity : AppCompatActivity() {



@AndroidEntryPoint
class PlantDetailFragment : Fragment() {

    private val plantDetailViewModel: PlantDetailViewModel by viewModels()

sunflower 仓库地址

gd771747384/sunflower

相关推荐
虾球xz1 小时前
游戏引擎学习第198天
学习·游戏引擎
网络安全指导员2 小时前
如何在JMeter中配置断言,将非200状态码视为测试成功
网络·学习·jmeter·安全·web安全·架构
浪淘沙jkp2 小时前
大模型学习四:‌DeepSeek Janus-Pro 多模态理解和生成模型 本地部署指南(折腾版)
python·学习·deepseek
Kx…………2 小时前
Uni-app入门到精通:uni-app的基础组件
前端·css·学习·uni-app·html
~樱小路~2 小时前
网络:华为数通HCIA学习:IP路由基础
网络·学习·华为
吴梓穆3 小时前
UE5学习笔记 FPS游戏制作42 按钮添加回调函数
笔记·学习·ue5
吴梓穆3 小时前
UE5学习笔记 FPS游戏制作39 制作一个带有背景的预制面板 使用overlay和nameSlot
笔记·学习·ue5
云上艺旅1 天前
K8S学习之基础七十四:部署在线书店bookinfo
学习·云原生·容器·kubernetes
你觉得2051 天前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义下载方法
大数据·人工智能·python·gpt·学习·机器学习·aigc
A旧城以西1 天前
数据结构(JAVA)单向,双向链表
java·开发语言·数据结构·学习·链表·intellij-idea·idea