ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 Coroutine Flow - 2 (Flow 사용)
    안드로이드 학습/Android 기술면접 대비 2024. 11. 28. 10:48

    1편에서 flow 사용법을 app architecture 예제와 같이 보긴 했지만 좀더 쉽게 이것 저것 활용해 보기 위해 예제를 새로 다시 하나 만들었다. 

     

    1. Producer(생산자)

    private fun coroutineFlowProducer(): Flow<Int> {
        val flowBuilder: Flow<Int> = flow {
            for (num in 1..10) {
                emit(num)
            }
        }
        return flowBuilder
    }
    

     

    먼저 1 부터 10까지 방출하는 flow builder를 만들었다.

     

    2. Intermediary

    private fun coroutineFlowIntermediary(flowBuilder: Flow<Int>): Flow<Int> {
        val newFlowBuilder =
            flowBuilder
                .onEach {
                    delay(1000L)
                    binding.tvCoroutineFlowProducerNumber.text = "$it"
                } // 각 아이템마다 1초 대기
                .flowOn(Dispatchers.Main)
                .filter { it % 2 == 1 }
                .flowOn(Dispatchers.IO)
                .onEach {
                    binding.tvCoroutineFlowIntermediaryNumber.text = "filter { it % 2 == 1 } \n\n $it"
                }
                .flowOn(Dispatchers.Main)
                .map { it * 2 }
                .flowOn(Dispatchers.IO)
    
        return newFlowBuilder
    }
    • 해당 flowbuilder를 parameter로 받온다.
    • 그 다음 filter 연산자로 홀수만 받아온다.
    • 그 다음 filter된 값에 map 연산자로 * 2를 해준다.
    • 중간에 flowOn으로 CoroutineContext를 변경해줬다. 왜냐하면 text를 바꾸는건 Main thread에서 가능하고 연산은 비동기로 해주고 싶어서 그랬다. 

    3. Consumer

    private suspend fun coroutineFlowConsumer(flowBuilder: Flow<Int>){
        flowBuilder.collect{
            value -> binding.tvCoroutineFlowTest.text = "$value"
        }
    }

     

    마지막으로 collect를 사용해서 결과값을 받아온다.

     

    emit 되는 값은 : 1,2,3,4,5,6,7,8,9,10

    filter 되는 값은 : 1,3,5,7,9

    map 되는 값은 : 2, 6, 10, 14, 18

    collect 되는 값은 :  2, 6, 10, 14, 18

     

    override fun initContentInOnViewCreated() {
    
        // 1. Producer(생산자)
        val flowProducerTest = coroutineFlowProducer()
    
        // 2. Intermediary(중간 연산자)
        val flowIntermediaryTest = coroutineFlowIntermediary(flowProducerTest)
    
        // 3. Consumer(소비자)
        CoroutineScope(Dispatchers.Main).launch {
            coroutineFlowConsumer(flowIntermediaryTest)
        }
    
    }

     

    마지막으로 collect를 할때는 코루틴으로 감싸줘야한다. 

     

Designed by Tistory.