[Kotlin] Coroutine의 SharedFlow 와 Channel

sundays·2023년 4월 5일
1

coroutine

목록 보기
4/7

이번에는 Channel을 SharedFlow와 비교 해볼것입니다. 저는 이전에 SharedFlow와 관련한 포스팅을 한적이 있습니다. Shared flow는 hot flow로 comsumer들에게 send를 해주는 channel과 동일한 방식으로 작동됩니다. 다만 사용성에 대해서는 차이가 있는데요 해당 내용을 살펴보겠습니다. 이전 channel에서 사용한것과 마찬가지로 viewmodel에 SharedFlow를 사용해서 이 flow가 계속 될 수 있게 진행 할 것입니다.

SharedFlow

viewmodel에 Int형 데이터를 담을 수 있는 MutableSharedFlow를 선언하겠습니다.

class MainViewModel : ViewModel() {
	private val _sharedFlow = MutableSharedFlow<Int>();
	val sharedFlow = _sharedFlow.asSharedFlow();
    
    init {
    	viewModelScope.launch {
        	repeat(100000) {
            	sharedFlow.emit(it)
                delay(1000)
            }
        }
    }
}

sharedFlow for-loop를 10만번 가량돌면서 그것을 consumer에게 제공하기 위해 sharedFlow에 emit(it)하였습니다. 이것은 hot flow이기 때문에 연속해서 리턴됩니다.

override void onCreate(savedInstanceState) {
	super.onCreate(savedInstanceState);
    lifecycleScope.launch {
    	repeatOnLifecycle(Lifecycle.State.STARTED) {
        	viewmodel.sharedFlow.collect { number ->
            	println("Collected $number from sharedFlow")
            }
        }
    }
}

[결과]

I/System.out: Collected 0 from sharedFlow
I/System.out: Collected 1 from sharedFlow
I/System.out: Collected 2 from sharedFlow
I/System.out: Collected 3 from sharedFlow
I/System.out: Collected 4 from sharedFlow
I/System.out: Collected 5 from sharedFlow
I/System.out: Collected 6 from sharedFlow
I/System.out: Collected 7 from sharedFlow
I/System.out: Collected 8 from sharedFlow
I/System.out: Collected 9 from sharedFlow
I/System.out: Collected 10 from sharedFlow
I/System.out: Collected 11 from sharedFlow
I/System.out: Collected 12 from sharedFlow
-- 백그라운드 프로세스로 변경 --
I/System.out: Collected 22 from sharedFlow
I/System.out: Collected 23 from sharedFlow
I/System.out: Collected 24 from sharedFlow
I/System.out: Collected 25 from sharedFlow
I/System.out: Collected 26 from sharedFlow
I/System.out: Collected 27 from sharedFlow
I/System.out: Collected 28 from sharedFlow
I/System.out: Collected 29 from sharedFlow
I/System.out: Collected 30 from sharedFlow

Channel

SharedFlow와 동일하게 channel도 같은 내용의 flow를 계속해서 consumer에게 보내는 코드 입니다.

class MainViewModel : ViewModel() {
	private val channel = Channel<Int>();
	val flow = channel.receiveAsFlow();
    
    init {
    	viewModelScope.launch {
        	repeat(100000) {
            	sharedFlow.send(it)
                delay(1000)
            }
        }
    }
}

해당 코드를 activity에 같이 적용하여 시작 시점 부터 collect를 하겠습니다. receiveAsFlow() 로 실행되기 때문에 flow처럼 channel을 사용한 것입니다

		lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.flow.collect { number ->
                    println("Collected $number from channel")
                }
            }
        }

[결과]

I/System.out: Collected 0 from channel
I/System.out: Collected 1 from channel
I/System.out: Collected 2 from channel
I/System.out: Collected 3 from channel
I/System.out: Collected 4 from channel
I/System.out: Collected 5 from channel
-- 백그라운트 프로세스로 변경 --
I/System.out: Collected 6 from channel
I/System.out: Collected 7 from channel
I/System.out: Collected 8 from channel
I/System.out: Collected 9 from channel
I/System.out: Collected 10 from channel
I/System.out: Collected 11 from channel

결론

Channel은 sharedFlow와 다르게 앱이 백그라운드로 전환될때 이벤트가 전송된 이벤트를 실제로 캐시한다음에 consumer가 다시 호출하면 캐시 된 내용들을 리턴하는 방식을 사용합니다. 채널은 단일 observer를 가진 viewmodel을 사용한 경우에 많이 쓰이며 multiple-observer를 가질때는 sharedflow를 사용하여 여러 다른 위치에서 이벤트를 관찰 할 수 있게 됩니다.

전체 소스를 확인할 수 있게 github 링크를 첨부합니다.

Reference

profile
develop life

0개의 댓글