简体   繁体   中英

Android + Kotlin + Hilt: How to provide. SQLiteDatabase

I'm implementing Hilt in my multi-module Android app and not being able to provide/inject SQLiteDatabase (I was trying to look for help before posting, but none found regarding SQLiteDatabase).

My first attempt was the next:

@Module
@InstallIn(SingletonComponent::class)
class Database {

    @Provides
    @Singleton
    fun provideDatabase(database: SQLiteDatabase): SQLiteDatabase {
        return database
    }
}

But the builder complains:

error: [Dagger/MissingBinding] android.database.sqlite.SQLiteDatabase cannot be provided without an @Inject constructor or an @Provides-annotated method.

I thought that might be:

@Provides
@Singleton
fun provideDatabase(): SQLiteDatabase {
    return SQLiteDatabase()
}

But now it complains init is private in SQLiteDatabase.

I'm stuck, and I don't know how to provide database to repositories, what I'm trying to do in constructor this way:

class TrackRepository
@Inject constructor(
    private var database: SQLiteDatabase) {
    ...
}

Edit 1: Moving the database "Provides" from Repository module to app module the error is completely different. Now it complains about a dependency cycle, but for me it's difficult to understand the error message clearly:

/app/build/generated/hilt/component_sources/debug/com/myapp/myapp/app/AWApplication_HiltComponents.java:135: error: [Dagger/DependencyCycle] Found a dependency cycle:
  public abstract static class SingletonC implements AWApplication_GeneratedInjector,
                         ^
      android.database.sqlite.SQLiteDatabase is injected at
          com.myapp.myapp.app.Dependencies.provideDatabase(database)
      android.database.sqlite.SQLiteDatabase is injected at
          com.myapp.myapp.app.Dependencies.provideDatabase(database)
      ...
  
The cycle is requested via:
  android.database.sqlite.SQLiteDatabase is injected at
      com.artandwords.repository.local.ThoughtRepository(database, …)
  com.artandwords.repository.local.ThoughtRepository is injected at
      services.ThoughtService(repository)
  services.ThoughtService is injected at
      com.myapp.myapp.activities.thought.DisplayThoughtViewModel(…, thoughtService, …)
  com.myapp.myapp.activities.thought.DisplayThoughtViewModel is injected at
      com.myapp.myapp.activities.thought.DisplayThoughtViewModel_HiltModules.BindsModule.binds(arg0)
  @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
      dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.myapp.myapp.app.AWApplication_HiltComponents.SingletonC → com.myapp.myapp.app.AWApplication_HiltComponents.ActivityRetainedC → com.myapp.myapp.app.AWApplication_HiltComponents.ViewModelC]

Ok, I found the solution myself. Instead of trying to provide SQLiteDatabase directly I tried providing my SQLiteHelper, which extends SQLiteOpenHelper, and so I have access to readableDatabase and writableDatabase.

Not yet sure if it'll work, because the "provideDatabase" method is not marked in yellow in Android Studio (in the sense of being referenced by any class), but at least now the app builds.

@Module
@InstallIn(SingletonComponent::class)
class Database {

    @Provides
    @Singleton
    fun provideDatabase(database: SQLiteHelper): SQLiteHelper {
        return database
    }
}

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