[英]StateFlow not Trigger Loading() when back from another activity
Situation情况
Example I have 2 activities, Activity Menu
and Activity Detail
.示例我有 2 个活动,
Activity Menu
和Activity Detail
。 Flow system is, I go to Activity Menu
, click a button to Activity Detail
.流程系统是,我go到
Activity Menu
,点击一个按钮到Activity Detail
。 I updated the data from Activity Detail
.我更新了
Activity Detail
中的数据。 When press Back Button at the phone, only Resource Success
trigger, not the Resource Loading
.当在手机上按下返回键时,只会触发
Resource Success
,不会触发Resource Loading
。
Codes Relevant代码相关
Resource class资源 class
sealed class Resource<T>(
val data: T? = null,
val message: String? = null,
val messageInt: Int? = null,
val code: Int? = null,
val errorReader: Reader? = null,
) {
class Initialize<T> : Resource<T>()
class Loading<T>(data: T? = null) : Resource<T>(data)
class Success<T>(data: T?) : Resource<T>(data)
class Error<T>(
message: String? = null,
messageInt: Int? = null,
data: T? = null,
code: Int? = null,
errorReader: Reader? = null
) :
Resource<T>(data, message, messageInt, code, errorReader)
}
At ViewModel在 ViewModel
private val _itemList = MutableStateFlow<Resource<Int>>(Resource.Initialize())
val itemList: StateFlow<Resource<Int>> = _itemList
init {
viewModelScope.launch {
getItemList()
}
}
suspend fun getItemList() = viewModelScope.launch {
_itemList.emit(Resource.Loading())
val data = withContext(ioDispatcher + coroutineExceptionHandler) {
return@withContext quickSave.getInt(Constant.BROKEN_TOTE_LIST_COUNT, 0)
}
//Only this Success trigger for 2nd time
_itemList.emit(Resource.Success(data = data))
}
At the Activity活动现场
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityToteBrokenBinding.inflate(layoutInflater)
val root = binding.root
setContentView(root)
startLifeCycle()
}
private fun startLifeCycle() {
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
collectItemList()
}
}
}
}
private suspend fun collectItemList() {
viewModel.itemList.collectLatest {
when (it) {
is Resource.Initialize -> {
}
is Resource.Loading -> {
Log.i("???","Resource Loading")
showLoading()
}
is Resource.Success -> {
Log.i("???","Resource Success")
handleSuccess()
hideLoading()
}
is Resource.Error -> {
hideLoading()
}
}
}
}
Here is the Output这是Output
---------------------------- PROCESS STARTED (30051) for package com.company.com ----------------------------
2022-09-29 12:21:51.977 30051-30051 ??? com.company.com I Resource Loading
2022-09-29 12:21:52.137 30051-30051 ??? com.company.com I Resource Success
2022-09-29 12:22:10.839 30051-30051 ??? com.company.com I Resource Success
The Output not trigger Resource Loading
. Output 没有触发
Resource Loading
。 How to make it trigger again every time I back from the Activity Detail
?每次我从
Activity Detail
返回时如何让它再次触发?
First as in your getItemList()
method you are already using viewModelScope.launch
, you can remove the suspend
modifier from it.首先,在您已经在使用
viewModelScope.launch
的getItemList()
方法中,您可以从中删除suspend
修饰符。
The 2nd time success is not getting triggered from your view model function but because you are using lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED)
hence the flow is getting collected again after coming back to the activity.第二次成功不是从您的视图 model function 中触发,而是因为您正在使用
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED)
因此在返回活动后再次收集流程。
So in your menu activity you can override onResume
method, and in that you can call the view model function getItemList()
, which will then emit in your expected sequence.因此,在您的菜单活动中,您可以
override onResume
方法,并且您可以调用视图 model function getItemList()
,然后它将按您预期的顺序发出。
Only drawback is that it will get trigger on every onResume, even when Lock/Unlock happens or you are returning to the app from background.唯一的缺点是它会在每次 onResume 时触发,即使发生锁定/解锁或您从后台返回应用程序时也是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.