Hello all,
I have tried to use coroutines in my code. I use it when fetching data from the backend server and accessing realm database. Unfortunately it somehow does not work (or I misuse it, please help .-)) as I get below exception when writing to the database:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-3
Process: ua.allatra.org.audio.library, PID: 18933
java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
at io.realm.BaseRealm.checkIfValid(BaseRealm.java:442)
at io.realm.Realm.where(Realm.java:1430)
at ua.allatra.org.audio.library.db.RealmHandler.createNewAudioTrackDAO(RealmHandler.kt:127)
at ua.allatra.org.audio.library.ui.adapter.AudioTrackDownloadAdapter$fetchAudioIfExistsElseConvert$2.invokeSuspend(AudioTrackDownloadAdapter.kt:294)
at ua.allatra.org.audio.library.ui.adapter.AudioTrackDownloadAdapter$fetchAudioIfExistsElseConvert$2.invoke(Unknown Source:10)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:154)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at ua.allatra.org.audio.library.ui.adapter.AudioTrackDownloadAdapter.fetchAudioIfExistsElseConvert(AudioTrackDownloadAdapter.kt:287)
at ua.allatra.org.audio.library.ui.adapter.AudioTrackDownloadAdapter$ViewHolder$bind$1$1.invokeSuspend(AudioTrackDownloadAdapter.kt:261)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:561)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:727)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:667)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:655)
I init realm globally like this in the adapter:
launch(Dispatchers.IO) {
withContext(Dispatchers.IO) {
realmHandler = RealmHandler(parent.context)
}
}
Writing like this:
private suspend fun updateDownloadedTrack(it: AudioTrackObject) =
withContext(Dispatchers.IO){
Log.d(TAG, "ApiId = ${it.apiId} track downloaded.")
realmHandler.updateExistingAudioTrackDAO(
it.apiId,
it.isConverting,
it.isDownloading,
it.filePath
)
}