0

问题

Cannot invoke setValue on a background thread在使用时MutableStateFlow收到错误消息ActivityLifecycleCallback,我在将生命周期喷气背包更新到 2.4.0 并使用后收到此错误repeatOnLifecycle。使用由 koin 注入到 ActivityLifecycleCallback 中响应的活动的视图模型调用网络接口。

执行

打回来

class ActivityLifecycleCallback :
    Utils.ActivityLifecycleCallbacks(),
    KoinComponent {
    private val mPref by inject<SecuredPrefUseCase>()
    private var mViewModel: Lazy<AccountViewModel>? = null

    override fun onActivityCreated(activity: Activity) {
        super.onActivityCreated(activity)
        if (activity is AppCompatActivity) {
            mViewModel = activity.viewModel()
            if (activity is AccountObserver.Interfaces) {
                mViewModel?.let {
                    activity.lifecycle.addObserver(
                        AccountObserver(activity, it.value)
                    )
                    activity.supportFragmentManager.fragments.forEach { frg ->
                        if (frg is AccountObserver.Interfaces) {
                            frg.viewLifecycleOwner.lifecycle.addObserver(
                                AccountObserver(frg, it.value)
                            )
                        }
                    }
                }
            }
        }
    }

    override fun onActivityStarted(activity: Activity) {
        if (mPref.membership != MembershipType.GUEST) {
            mViewModel?.value?.getMembership()
        }
        super.onActivityStarted(activity)
    }
}

视图模型

class AccountViewModel(
    private val useCase: AccountUseCase,
) : BaseViewModel() {
    private val _membership = MutableStateFlow<State.Single<Membership.Data?>>(State.Single.Idle())
    val mMembership get() = _membership.asImmutable()

    suspend fun resetMembership() {
        _membership.emit(State.Single.Idle())
    }

    fun getMembership() = viewModelScope.launch(ioContext) {
        requestSingle(_membership) {
            useCase.getMembership()
        }
    }
    
    suspend inline fun <R> BaseViewModel.requestSingle(
    state: MutableStateFlow<State.Single<R>>,
    delay: Long = Constant.MEDIUM_DELAY,
    crossinline block: suspend () -> R,
    ) = mutex.withLock {
        flow {
            emit(State.Single.Loading())
            val result = block.invoke()
            delay(delay)
            emit(State.Single.Success(result))
        }.catch {
            state.emit(State.Single.Failed(it))
        }.collect {
            state.emit(it)
        }
    }
}

观察者

class AccountObserver(
    private val view: Interfaces,
    private val viewModel: AccountViewModel,
) : DefaultLifecycleObserver {

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        owner.initObserver {
            viewModel.mMembership.observeSingle(this) {
                when (it) {
                    is State.Single.Idle -> view.onMembershipIdle()
                    is State.Single.Loading -> view.onMembershipLoading()
                    is State.Single.Success -> {
                        view.onMembershipSuccess(it.data)
                        viewModel.resetMembership()
                    }
                    is State.Single.Failed -> {
                        view.onMembershipFailed(it.throwable)
                        viewModel.resetMembership()
                    }
                }
            }
        }
    }
}

inline fun LifecycleOwner.initObserver(
    crossinline block: suspend CoroutineScope.() -> Unit,
) {
    lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            block.invoke(this)
        }
    }
}

suspend inline fun <R> StateFlow<State.Single<R>>.observeSingle(
    coroutineScope: CoroutineScope,
    crossinline block: suspend (State.Single<R>) -> Unit,
) {
    coroutineScope.launch {
        collect {
            block.invoke(it)
        }
    }
}
4

0 回答 0