Reputation: 1667
I have a method to fetch devices using coroutines and use viewModelScope.launch
to run coroutines. I want to catch errors using CoroutineExceptionHandler
, but I get the error:
E/[Koin]: Instance creation error : could not create instance for [Factory:'com.test.presentation.viewModel.ActivateDeviceViewModel']: java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter context
kotlin.coroutines.CombinedContext.plus(Unknown Source:2)
kotlinx.coroutines.CoroutineContextKt.newCoroutineContext(CoroutineContext.kt:33)
kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:52)
kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
com.test.presentation.viewModel.ActivateDeviceViewModel.fetchDevices(ActivateDeviceViewModel.kt:42)
com.test.presentation.viewModel.ActivateDeviceViewModel.<init>(ActivateDeviceViewModel.kt:29)
com.test.di.ModulesKt$viewModelModule$1$2.invoke(Modules.kt:63)
com.test.di.ModulesKt$viewModelModule$1$2.invoke(Modules.kt:63)
org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:103)
org.koin.core.scope.Scope.resolveInstance(Scope.kt:236)
org.koin.core.scope.Scope.access$resolveInstance(Scope.kt:34)
org.koin.core.scope.Scope$get$1.invoke(Scope.kt:199)
org.koin.core.time.MeasureKt.measureDurationForResult(Measure.kt:75)
org.koin.core.scope.Scope.get(Scope.kt:198)
com.test.presentation.fragment.ActivateDeviceFragment$special$$inlined$inject$default$1.invoke(ComponentCallbackExt.kt:69)
kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
com.test.presentation.fragment.ActivateDeviceFragment.getViewModel(ActivateDeviceFragment.kt:39)
com.test.presentation.fragment.ActivateDeviceFragment.access$getViewModel(ActivateDeviceFragment.kt:37)
com.test.presentation.fragment.ActivateDeviceFragment$handleActivateDeviceResult$1$1.invokeSuspend(ActivateDeviceFragment.kt:51)
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
androidx.lifecycle.DispatchQueue.drainQueue(DispatchQueue.kt:75)
androidx.lifecycle.DispatchQueue.resume(DispatchQueue.kt:54)
androidx.lifecycle.LifecycleController$observer$1.onStateChanged(LifecycleController.kt:40)
androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:265)
androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:307)
androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:148)
androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
androidx.fragment.app.Fragment.performStart(Fragment.java:3024)
androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:568)
androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:277)
androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1327)
androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2757)
androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2707)
androidx.fragment.app.Fragment.performStart(Fragment.java:3028)
androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:568)
androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:277)
androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1327)
androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2757)
androidx.fragm.
Please tell me what am I doing wrong and how to fix it? Thanks
fragment
class ActivateDeviceFragment : Fragment(R.layout.fragment_activate_device) {
private val viewModel: ActivateDeviceViewModel by inject()
// ....
}
view model
class ActivateDeviceViewModel constructor(
private val activateDeviceUseCase: ActivateDeviceUseCase,
) : ViewModel() {
init {
fetchDevices()
}
private val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
Timber.tag("test").d(throwable)
}
private fun fetchDevices() {
viewModelScope.launch(exceptionHandler) {
}
}
}
koin modules
val useCaseModule = module {
single { ActivateDeviceUseCase() }
}
val viewModelModule = module {
viewModel { ActivateDeviceViewModel(get() }
}
Upvotes: 3
Views: 2498
Reputation: 31
It is not related to Koin.
The log shows that the exceptionHandler
in viewModelScope.launch(exceptionHandler)
is actually null, and which throws NullPointerException
.
It is because you trigger the fetchDevices()
inside init{}
, in which the instantiation of exceptionHandler
is not ready (means it is null).
Therefore, you should not call fetchDevices()
inside init{}
. For example, you could call this in your Fragment onViewCreated(){ viewModel.fetchDevices }
instead. It will be fine.
Upvotes: 3