Android - java.lang.IllegalStateException: 必须在主线程上调用方法 addObserver

Android - java.lang.IllegalStateException: Method addObserver must be called on the main thread

尝试访问视图模型时抛出异常。 异常抱怨调用 addObserver,但我在代码路径中看不到任何可能调用 addObserver 的内容 片段

@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<String, Any>
        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.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)"

视图模型是在访问时延迟创建的,视图模型的创建必须在主线程上完成。在全局范围内访问它之前,只需尝试在主线程上访问视图模型即可解决问题

// 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) {}
}