Issue
I have the following in my viewmodel
val currentStockPriceAsLiveData: LiveData<UiState> = stockPriceDataSource.latestStockList
.map { listOfStock ->
UiState.Success(listOfStock)
}.asLiveData()
I observe this in my Activity in the onCreate method
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.currentStockPriceAsLiveData.observe(this@FlowUseCase1Activity) { uiState ->
if (uiState != null) {
if(uiState is UiState.Success) {
Timber.d("Received ${uiState.stockList.first()}")
}
render(uiState)
}
}
}
}
}
I am using repeatOnLifeCycle to only observe when the lifecycle is at least STARTED state. This works as if I put the app in the background it will stop observing.
However, the problem is when I bring the app back to the foreground it will trigger duplicated emissions. And when I put the app to the background a second time it will trigger triple emissions.
From my log:
00:00:05.274 23476-23476 D Received Stock(rank=1, name=Apple, symbol=AAPL, marketCap=2.37819317E12, country=United States, currentPrice=142.95015, currency=DOLLAR, priceTrend=UNKNOWN)
00:00:05.275 23476-23476 D Received Stock(rank=1, name=Apple, symbol=AAPL, marketCap=2.37819317E12, country=United States, currentPrice=142.95015, currency=DOLLAR, priceTrend=UNKNOWN)
00:00:05.276 23476-23476 D Received Stock(rank=1, name=Apple, symbol=AAPL, marketCap=2.37819317E12, country=United States, currentPrice=142.95015, currency=DOLLAR, priceTrend=UNKNOWN)
As you can see its like its triggering 3 times at the same time.
I think it is because when I put the app to the background the viewmodel has not been destroyed, so when I put the app back in the foreground it creates subsequent observers.
Is there a way to prevent this?
Solution
You don't have to manage the lifecycle of LiveData. LiveData manages its own lifecycle. It will pause or resume based on lifecycle of containing Activity and Fragment.
Use LiveData like this in onCreate()
viewModel.currentStockPriceAsLiveData.observe(this@FlowUseCase1Activity) { uiState ->
if (uiState != null) {
if(uiState is UiState.Success) {
Timber.d("Received ${uiState.stockList.first()}")
}
render(uiState)
}
}
I don't know exactly why it's duplicating. It may be because you attach a new observer each time the lifecycle reach STARTED STATE. LiveData does not need to be attached each time the lifecycle changes. It manages its own lifecycle. Call live data as shown above in onCreate() just once.
Answered By - Abdul Muqeet
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.