通过SunFlower学习Hilt基本使用

news/2025/1/15 13:54:32/

文章目录

    • 添加hilt配置
    • 数据库自动注入
      • 常规kotlin 规范创建AppDatabase、表、查询封装Dao
      • 创建DatabaseModule,向外提供数据库访问方法
      • @InstallIn和@Provider上Scope关系
      • PlantRepository 使用 PlantDao
      • ViewModel使用PlantRepository
      • Fragment声明需要进行注入
      • sunflower 仓库地址

根据理解,使用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(): GardenPlantingDaoabstract fun plantDao(): PlantDaocompanion object {// For Singleton instantiation@Volatile private var instance: AppDatabase? = nullfun 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#4785private 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 daysval 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@Providesfun provideAppDatabase(@ApplicationContext context: Context): AppDatabase {return AppDatabase.getInstance(context)}@Providesfun providePlantDao(appDatabase: AppDatabase): PlantDao {return appDatabase.plantDao()}

@InstallIn和@Provider上Scope关系

@InstallIn指定module要注入的生成的component,@Provider函数可以添加Scoped限定符,但是必须与@InstallIn作用域一致。
@Provider函数添加Scoped限定符后,在component范围内仅仅创建一个实例。

Android 类生成的组件作用域
ApplicationSingletonComponent@Singleton
ActivityActivityRetainedComponent@ActivityRetainedScoped
ViewModelViewModelComponent@ViewModelScoped
ActivityActivityComponent@ActivityScoped
FragmentFragmentComponent@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


http://www.ppmy.cn/news/1020632.html

相关文章

最好的和解,是陪“内在小孩”一起长大

“为什么我总是很心累&#xff1f;” 经常莫名感到心累、有深深的无力感&#xff0c;是现代成年人的通病。 生活压力大&#xff0c;忙忙碌碌却觉得迷茫、空虚、压抑&#xff1b; 不管怎么努力&#xff0c;好像总是卡在某个地方&#xff0c;得不到升职加薪&#xff1b; 每段感情…

javaee dom4j读取xml文件

引入jar包 dom4j-1.6.1.jar 创建xml文件 <?xml version"1.0" encoding"UTF-8"?> <books><book id"1"><title ID"t1">背影</title><price>88</price><author>三毛</author>…

hive on tez资源控制

sql insert overwrite table dwintdata.dw_f_da_enterprise2 select * from dwintdata.dw_f_da_enterprise; hdfs文件大小数量展示 注意这里文件数有17个 共计321M 最后是划分为了21个task 为什么会有21个task&#xff1f;不是128M 64M 或者说我这里小于128 每个文件一个map…

灰度均衡变换之c++实现(qt + 不调包)

1.基本原理 灰度均衡是以累计分布函数变换为基础的直方图修正法&#xff0c;它可以产生一副灰度级分布概率均匀的图像。也就是说&#xff0c;经过灰度均衡后的图像在没一级灰度上像素点的数量相差不大。公式见下图&#xff0c;为灰度值为x的像素点的个数&#xff0c;n为总像素点…

8.7 校招 内推 面经

绿泡泡&#xff1a; neituijunsir 交流裙&#xff0c;内推/实习/校招汇总表格 1、自动驾驶一周资讯 - 特斯拉开发FSD有望年底实现完全自动驾驶&#xff0c;丰田/小马智行拟成立合资公司&#xff0c;7月新能源车企销量出炉 https://mp.weixin.qq.com/s/6_c6ZvvCjXItPx5mwh51…

测试角色在项目各阶段的项目管理tips

目录 一、前言 二、现状及思考 三、详谈测试介入各阶段的项目管理tips 四、暴露风险最终与协作方共同确定运作策略 五、总结 资料获取方法 一、前言 项目管理是一个繁杂的过程&#xff0c;每个阶段需要涉及到不同人员、资源的协调配合。每个角色都有自己的定位和任务&…

每天一道leetcoed:剑指 Offer 28. 对称的二叉树(适合初学者树)

今日份题目&#xff1a; 请实现一个函数&#xff0c;用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样&#xff0c;那么它是对称的。 例如&#xff0c;二叉树 [1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2,null,3,nu…