问题
我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)
}
}
}