【问题标题】:Can't inject Room dao using Hilt, Android无法使用 Hilt,Android 注入 Room dao
【发布时间】:2021-03-10 19:41:08
【问题描述】:

我正在尝试使用 Hilt 将 Room DAO 注入到存储库中。 我正在使用以下代码:

def room_version = "2.2.6"
ext.hilt_version = '2.33-beta'

implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
implementation "androidx.room:room-guava:$room_version"
testImplementation "androidx.room:room-testing:$room_version"

implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

DAO

@Dao
interface SearchDAO {

    @Query("SELECT * FROM searches_table WHERE name LIKE '%' || :query || '%'")
    fun readSearches(query : String) : Flow<List<SearchItem>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertSearch(search : SearchItem)

    @Delete
    suspend fun deleteSearch(search: SearchItem)
}

数据库

@Database(
        entities = [SearchItem::class],
        version = 1
)
abstract class SearchesDatabase : RoomDatabase(){
    abstract fun getSearchesDao() : SearchDAO
}

提供者

@Module
@InstallIn(ActivityComponent::class)
object AppModule{
    @Singleton
    @Provides
    fun provideSearchDatabase(@ApplicationContext context : Context) =
        Room.databaseBuilder(context, SearchesDatabase::class.java, SEARCH_DATABASE_NAME)
            .fallbackToDestructiveMigration()
            .build()

    @Provides
    fun provideSearchDAO(appDatabase: SearchesDatabase): SearchDAO {
        return appDatabase.getSearchesDao()
    }
}

基础应用程序

@HiltAndroidApp
class BaseApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        //Timber.plant(Timber.DebugTree())
    }
}

存储库注入

class Repository @Inject constructor(
    val searchesDao : SearchDAO
){
...
}

问题是我收到以下错误:

[Dagger/MissingBinding] com.example.leagueapp.database.SearchDAO 如果没有 @Provides-annotated 方法,则无法提供。民众 抽象静态类 SingletonC 实现 BaseApplication_GeneratedInjector

【问题讨论】:

  • 尝试使用@InstallIn(ApplicationComponent::class) 而不是@InstallIn(ActivityComponent::class)
  • 谢谢,但我认为已弃用,使用当前刀柄版本找不到它
  • 我想通了,我必须使用 SingletonComponent。感谢@KishanMaurya 的输入

标签: android kotlin android-room dagger-hilt


【解决方案1】:

请在您的 App Module 类中编写以下代码。您只需要在 @installIn() 注释中编写 SingletonComponent::class 而不是 ActivityComponent::class :)

@Module
@InstallIn(SingletonComponent::class)
object AppModule{
    @Singleton
    @Provides
    fun provideSearchDatabase(@ApplicationContext context : Context) =
        Room.databaseBuilder(context, SearchesDatabase::class.java, SEARCH_DATABASE_NAME)
            .fallbackToDestructiveMigration()
            .build()

    @Provides
    fun provideSearchDAO(appDatabase: SearchesDatabase): SearchDAO {
        return appDatabase.getSearchesDao()
    }
}

【讨论】:

    【解决方案2】:

    简短回答:任何@Singleton 都必须安装在 SingletonComponent 中。

    解释:单例的目的是为了他们所处的过程的生命。您的数据库是单例(可能应该是)但是您使用的是@InstallIn(ActivityComponent::class),它告诉dagger所有provided本模块中的范围应限于活动的生命周期;当 Activity 死亡时,模块也会死亡。

    【讨论】:

      猜你喜欢
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 2018-04-19
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2021-07-26
      • 2020-12-07
      相关资源
      最近更新 更多