作者:洪爷不是我 | 来源:互联网 | 2023-06-08 13:42
尝试访问视图模型时抛出异常。异常抱怨调用 addObserver,但我在代码路径中没有看到任何可能调用 addObserver Fragment 的内容@AndroidEntryPointclass
尝试访问视图模型时抛出异常。异常抱怨调用 addObserver,但我在代码路径中没有看到任何可能调用 addObserver Fragment 的内容
@AndroidEntryPoint
class ReferralEntryDialogFragment : DialogFragment() {
private val viewModel: ReferralEntryViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.applyCodeButton.setOnClickListener {
GlobalScope.launch {
try {
// Exception is thrown as soon as viewModel is accesses
// It does not get to applyCode function
viewModel.applyCode("code)
} catch (e: Exception) { }
}
}
}
}
视图模型
@HiltViewModel
class ReferralEntryViewModel @Inject constructor() : ViewModel() {
suspend fun applyCode(code: String): ApplyReferralResponse {
val result = Firebase.functions.getHttpsCallable("applyReferralCode")
.call(mapOf( "referralCode" to code))
.await()
val map = result?.data as Map
val jsOnString= Gson().toJson(map)
return Gson().fromJson(jsonString, ApplyReferralResponse::class.java)
}
}
堆栈跟踪
result = {StackTraceElement[20]@26993}
0 = {StackTraceElement@26901} "androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:317)"
1 = {StackTraceElement@26902} "androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:172)"
2 = {StackTraceElement@26903} "androidx.lifecycle.SavedStateHandleController.attachToLifecycle(SavedStateHandleController.java:49)"
3 = {StackTraceElement@26904} "androidx.lifecycle.SavedStateHandleController.create(SavedStateHandleController.java:70)"
4 = {StackTraceElement@26905} "androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:67)"
5 = {StackTraceElement@26906} "androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)"
6 = {StackTraceElement@26907} "dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:107)"
7 = {StackTraceElement@26908} "androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)"
8 = {StackTraceElement@26909} "androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)"
9 = {StackTraceElement@26910} "androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)"
10 = {StackTraceElement@26911} "androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)"
11 = {StackTraceElement@26912} "com.shivaapps.freeloaders.referral.ReferralEntryDialogFragment.getViewModel(Unknown Source:2)"
12 = {StackTraceElement@26913} "com.shivaapps.freeloaders.referral.ReferralEntryDialogFragment.access$getViewModel$p(ReferralEntryDialogFragment.kt:18)"
13 = {StackTraceElement@26914} "com.shivaapps.freeloaders.referral.ReferralEntryDialogFragment$onViewCreated$1$1.invokeSuspend(ReferralEntryDialogFragment.kt:41)"
14 = {StackTraceElement@26915} "kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)"
15 = {StackTraceElement@26916} "kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)"
16 = {StackTraceElement@26917} "kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)"
17 = {StackTraceElement@26918} "kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)"
18 = {StackTraceElement@26919} "kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)"
19 = {StackTraceElement@26920} "kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)"
回答
viewmodel 是在访问时惰性创建的,并且 viewmodel 的创建必须在主线程上完成。只需尝试在主线程上访问视图模型,然后再在全局范围内访问它就可以解决问题
// Access viewmodel so that it gets initialized on the main thread
viewModel
GlobalScope.launch
try {
// Exception is thrown as soon as viewModel is accesses
// It does not get to applyCode function
viewModel.applyCode("code)
} catch (e: Exception) {}
}