may I ask for a moment of your time? I've been stuck for days to understand about class initialization in android studio with kotlin. I really really need basic understanding about this one. This is really different. How to properly initialize class in Android?Why I keep getting error message "lateinit property db has not been initialized"?. A little bright spot would be much appreciated. Thank you and best regards
The problem is "private lateinit var db: AppDatabase" has not been initialized. Actually what is the correct way to initialize a class in Android with klotlin?
class PinjamanSuperRepository(
private val api: PinjamanApi,
private val preferences: UserPreferences
) : BasePinjamanRepository(){
private lateinit var db: AppDatabase
private val pagingSourceFactory = { db.pinjamanAktifDao.select_all() }
@ExperimentalPagingApi
fun getPinjamanAktif(): Flow<PagingData<Data>> {
return Pager(
config = PagingConfig(
pageSize = NETWORK_PAGE_SIZE,
enablePlaceholders = false
),
remoteMediator = PlayersRemoteMediator(
api,
db
),
pagingSourceFactory = pagingSourceFactory
).flow
}
companion object {
private const val NETWORK_PAGE_SIZE = 25
}
}
This is the AppDatabase Class
abstract class AppDatabase : RoomDatabase() {
abstract val pinjamanAktifDao: PinjamanAktifDao
abstract val remoteKeysDao: RemoteKeysDao
companion object {
@Volatile
private var instance: AppDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context) = instance
?: synchronized(LOCK) {
instance ?: buildDatabase(
context
).also {
instance = it
}
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"app_db"
).fallbackToDestructiveMigration()
.build()
}
}
Simple answer make whoever is creating the PinjamanSuperRepository
pass in the database.
class PinjamanSuperRepository(
private val api: PinjamanApi,
private val preferences: UserPreferences,
private val db: AppDatabase
) : BasePinjamanRepository()
//in viewmodel or whatever has access to a context.
val db = AppDatabase(getApplicationContext()) //however you get the AppDatabase.Companion.instance
val repo = PinjamanSuperRepository(api,preferences,db)
The problem your facing is you are using the RoomDatabse as a singleton which is fine, but access to it requries the user to supply a Context
regardless of it already being created. PinjamanSuperRepository
doesn't have access to Context
so it would never be able to create/retrieve the database by itself.
Quick but bad alternative
fun getPinjamanAktif(context: Context): Flow<PagingData<Data>>{
db = AppDatabase(context)
return Pager(...)
}