本文介绍了StateFlow收集发出NullPointerException异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我的存储库层有一个MutableStateFlow
,将其收集到我的ViewModel中。我在某些用户设备上收到此NPE
Fatal Exception: java.lang.NullPointerException
at a.b.c.ui.viewmodel.HomeViewModel$collectFlowState$$inlined$collect$1.emit(HomeViewModel.java:189)
at a.b.c.ui.viewmodel.HomeViewModel$collectFlowState$$inlined$collect$1$1.invokeSuspend(HomeViewModel.java:12)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTaskKt.java:176)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTaskKt.java:111)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.java:308)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.java:318)
at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.java:400)
at kotlinx.coroutines.android.HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1.run(HandlerContext.java:19)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7830)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1040)
MutableStateFlow
为非空数据,如果数据不知为何为空,应用程序将在较早时间崩溃。
我如何在存储库(生产者)层上使用StateFlow
的示例:
data class ApiData(...)
private val INITIAL = ApiData(...)
private var someState = INITIAL
private val dataSF = MutableStateFlow(someState)
fun dataFlow() = dataSF
// called on remote api success, we poll for updated data (delta) from the server
fun onDataChangeAvailable(x: Int, y: Double) {
someState = someState.copy(x = x, y= y)
dataSF.value = someState
}
ViewModel(消费者)端:
private val repository // constructor injected; repository is Application scoped
private val job = SupervisorJob()
private val uiScope = CoroutineScope(Dispatchers.Main + job)
// Viewmodel init block
init {
uiScope.launch {
repository.dataFlow().collect { // crash sometimes here.
// consume values
}
}
}
override fun onCleared() {
job.cancel()
super.onCleared()
}
和Flow doc建议捕获如下异常
try {
flow.collect { value ->
println("Received $value")
}
} catch (e: Exception) {
println("The flow has thrown an exception: $e")
}
那么,建议接受StateFlow
的collect
中的所有异常,还是只接受生产者端抛出的异常?NPE的一般原因是什么?推荐答案
我遇到了同样的问题。实际上,我正在将StateFlow映射到其他对象,并收集该对象。在映射过程中,我使用了!!
符号!删除该符号解决了我的问题。
这篇关于StateFlow收集发出NullPointerException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!