I want to provide a realm object in the background thread like this:
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
@Provides
@Singleton
fun provideDatabaseScope(): CoroutineScope = GlobalScope Dispatchers.IO
@Provides
@Singleton
fun provideDatabaseQueue(): ExecutorCoroutineDispatcher =
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
@Provides
@Singleton
fun provideGetRealmConfig(accountService: AccountService): GetRealmConfig =
GetRealmConfig(accountService)
@Provides
fun provideRealmConfig(
getRealmConfig: GetRealmConfig,
@ApplicationContext context: Context,
accountService: AccountService
): RealmConfigImpl = RealmConfigImpl(getRealmConfig, accountService, context)
@Provides
fun provideRealmCreator(
realmConfigImpl: RealmConfigImpl,
scope: CoroutineScope,
queue: ExecutorCoroutineDispatcher
): Realm {
return RealmCreator(realmConfigImpl, scope, queue).createRealmObject()!!
}
@Provides
@Singleton
fun provideUserDatabase(
realm: Realm,
databaseScope: CoroutineScope,
databaseQueue: ExecutorCoroutineDispatcher
): UserDataStorage = UserDataStorageImpl(realm, databaseScope, databaseQueue)
}
and this is RealmCreator class that creates the object in the background thread:
class RealmCreator @Inject constructor(
val realmConfigImpl: RealmConfigImpl,
val coroutineScope: CoroutineScope,
val executorCoroutineDispatcher: ExecutorCoroutineDispatcher
) {
var realm: Realm? = null
fun createRealmObject(): Realm? {
coroutineScope.launch(executorCoroutineDispatcher) {
try {
realm = Realm.getInstance(realmConfigImpl.realmConfiguration!!)
countDownLatch.countDown()
} catch (e: Exception) {
e.printStackTrace()
}
}
return realm
}
}
when I want to create a Realm object it returns null because this process is in a background thread. How can I create this object in this situation?
CodePudding user response:
Apart from your intention of realm object creation in the background, your code is an example of Unstructured Concurrency. You're passing CoroutineScope
in the constructor. You need to use coroutineScope()
as a global suspend function that creates a new CoroutineScope
under the hood and then executes the suspend function you pass with it in the body, and wait for it (and all its children) to complete before returning. It is a suspend function so you cannot call it outside of a coroutine like createRealmObject()
.
CodePudding user response:
I think you could use Provider in dagger. Reffer to this link.