简体   繁体   中英

Can't inject Room dao using Hilt, Android

I am trying to inject a Room DAO into a repository using Hilt. I am using the following code:

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

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

Providers

@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()
    }
}

Base Application

@HiltAndroidApp
class BaseApplication : Application() {

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

Repository injecting

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

And the problem is that I receive the following error:

[Dagger/MissingBinding] com.example.leagueapp.database.SearchDAO cannot be provided without an @Provides-annotated method. public abstract static class SingletonC implements BaseApplication_GeneratedInjector

Short answer: anything @Singleton must be installed in a SingletonComponent.

Explanation: singleton's are meant to live for the life of the process they are in. Your database is a singleton (as it probably should be) but you are using @InstallIn(ActivityComponent::class) which tells dagger that everything which is provide d in this Module should be scoped to the lifecycle of an activity; when the Activity dies the module dies.

please write the following code in your App Module class. you just need to write SingletonComponent::class instead of ActivityComponent::class in @installIn() annotation:)

@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()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM