HomeAndroidExploring Completely different Methods to Acquire Kotlin Circulation

Exploring Completely different Methods to Acquire Kotlin Circulation


That is a part of the asynchronous circulation collection:

Primary Kotlin Circulation Usages

You first have to create a circulation earlier than you’ll be able to accumulate it.

Create Circulation<T> and Emit T Worth

1. Create Circulation<T> Utilizing kotlinx.coroutines.circulation.circulation()

The primary parameter of the circulation() is the operate literal with receiver. The receiver is the implementation of FlowCollector<T> interface, which you’ll name FlowCollector<T>.emit() to emit the T worth.

2. Emit T Worth Utilizing FlowCollector<T>.emit()

On this code instance, the T is an Int. This circulation emits Int worth from 0 → 10,000 with a 1-second interval delay.

class FlowViewModel: ViewModel() 
{ 
    val circulation: Circulation<Int> = circulation { 
        repeat(10000) { worth -> 
            delay(1000) 
            emit(worth) 
        } 
    } 
}

The delay(1000) simulates the method of getting the worth that you simply wish to emit (from a community name for instance)

As soon as now we have the circulation, now you can accumulate the circulation. There are alternative ways of amassing circulation:

  • Circulation.collectAsState()

  • Circulation.accumulate()

Acquire Circulation – Circulation.collectAsState()

collectAsState() makes use of the poducestate() compose facet impact to gather the circulation and robotically convert the collected worth to State<T> for you.

@Composable
enjoyable FlowScreen() {
   val viewModel: FlowViewModel = viewModel()

   val flowCollectAsState =
       viewModel.circulation.collectAsState(preliminary = null)
}

Acquire Circulation – Circulation.accumulate()

To gather circulation, it is advisable to name Circulation<T>.accumulate() with FlowCollector<T> implementation. The operate definition seems to be like this:

public droop enjoyable accumulate(collector: FlowCollector<T>)

The primary parameter of the Circulation<T>.accumulate() is the FlowCollector<T> interface, which solely has one emit() operate.

public enjoyable interface FlowCollector<in T> {    
    public droop enjoyable emit(worth: T)  
}

It means it is advisable to implement the FlowCollector<T> interface, cross within the occasion of the implementation as the primary parameter to the Circulation<T>.accumulate() operate.

Nevertheless, when you have a look at the accumulate() utilization under, it would not seem like the pass-in parameter is the implementation of FlowCollector<T> interface?

circulation.accumulate { worth -> _state.worth = worth }

This can be a short-cut method of implementing FlowCollector<T> interface utilizing SAM conversion. As a result of FlowCollector<T> is practical interfacing, utilizing SAM conversion is allowed. The pass-in lambda is the override operate of the FlowCollector<T>.emit() operate interface.

When Circulation<T>.emit() is known as within the circulation that we created earlier, this line _state.worth = worth is executed. worth is the parameter that you simply cross into the emit() operate in the course of the circulation manufacturing in FlowViewModel above.

Since Circulation.accumulate() is a droop operate, it is advisable to launch a coroutine to name it. These are 3 ways you’ll be able to launch a coroutine:

  • ViewModel.viewModelScope.launch()

  • LifeCycleCoroutineScope.launchWhenStarted()

  • LifeCycleCoroutineScope.launch() with LifeCycle.repeatOnLifeCycle()

1. Acquire Circulation Utilizing ViewModel.viewModelScope.launch{}

class FlowViewModel: ViewModel() {  
    personal val _state: MutableState<Int?> = mutableStateOf(null)  
        val state: State<Int?> = _state  

    enjoyable viewModelScopeCollectFlow() {   
        viewModelScope.launch {  
            circulation.accumulate {  worth ->
                _state.worth = worth  
            } 
        }
    }
}

2. Acquire Circulation Utilizing LifeCycleCoroutineScope.LaunchWhenStarted()

class FlowViewModel: ViewModel() {
    personal val _state: MutableState<Int?> = mutableStateOf(null)
    val state: State<Int?> = _state

    enjoyable launchWhenStartedCollectFlow(lifeCycleScope: LifecycleCoroutineScope) {
        lifeCycleScope.launchWhenStarted {
            circulation.accumulate { worth ->
                _state.worth = worth
            }
        }   
    }
}

3. Acquire Circulation Utilizing LifeCycle.RepeatOnLifecycle()

class FlowViewModel: ViewModel() {
    personal val _state: MutableState<Int?> = mutableStateOf(null)
    val state: State<Int?> = _state

    enjoyable repeatOnCycleStartedCollectFlow(
        lifeCycleScope: LifecycleCoroutineScope,
        lifeCycle: Lifecycle) {

        lifeCycleScope.launch {
            lifeCycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                circulation.accumulate { worth ->
                    _state.worth = worth
                }
            }
        }
    }
}

Examine Varied Acquire Circulation Implementations

Let’s assume you have got already began amassing circulation, that is the abstract of what occurs in several lifecycle occasions.

Acquire Circulation Implementations ON_STOP / Background (not seen) ON_START / Background (seen) ON_DESTROY (Configuration Modified) ON_DESTROY (Lifecycle Dying)
collectAsState() Retains emitting Retains emitting Cancels emitting Cancels emitting
viewModelScope.launch() Retains emitting Retains emitting Retains emitting Cancels emitting
launchWhenStarted() Suspends emitting Resumes emitting Cancels emitting Cancels emitting
repeatOnLifecycle(Lifecycle.State.STARTED) Cancel emitting Restarts Emitting Cancels emitting Cancels emitting

So when you care about saving sources(i.e. not emitting something when the app is in background (not seen), you’ll be able to both use launchWenStarted() or repeatOnLifecycle(Lifecycle.State.STARTED). If you wish to droop and resume circulation emission, you employ launchWenStarted(). If you wish to restart the circulation emission once more, you employ repeatOnLifecycle(Lifecycle.State.STARTED)

Then again, when you do not care about losing sources, you should use both collectAsState() or viewModelScope.launch(). If you’d like the circulation to maintain emitting even after the configuration modified (e.g. display screen rotation), you employ viewModelScope.launch().

I believe it’s higher to point out the circulation chart as a substitute.

Exploring_Asynchronous_Kotlin_Flow_Usages_and_Behaviors_Flow_Chart.drawio.png

What I do not perceive is this text right here saying the launchWhenStarted() just isn’t protected to gather as a result of it retains emitting within the background when the UI just isn’t seen.

Nevertheless, I do not see this conduct based mostly on the experiment that I’ve carried out. It suspends the circulation emission and resumes it when the UI is seen once more.

To see extra particulars on launchWhenStarted() and repeatOnLifeCycle(), discuss with this text:

Conclusion

I’ve been utilizing viewModelScope.launch() to gather circulation. If the circulation would not continually emit worth, permitting the circulation to emit within the background would not waste any sources, for my part. Additionally, I needn’t care about canceling, restarting or resuming the circulation emission.

Then again, if the circulation is consistently emitting values, you might wish to think about using both launchWhenStarted() or repeatOnLifecycle(Lifecycle.State.STARTED).

Supply Code

GitHub Repository: Demo_AsyncFlow (see the FlowActivity)

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments