핵심 개념Flow는 콜드 스트림으로 각 구독자마다 독립적으로 실행되지만, SharedFlow와 StateFlow는 핫 스트림으로 여러 구독자가 하나의 데이터 소스를 공유합니다. SharedFlow여러 구독자가 동시에 같은 데이터를 받아야 할 때 사용합니다. 기본 사용법val sharedFlow = MutableSharedFlow()// 여러 구독자가 동시에 수신launch { sharedFlow.collect { println("구독자1: $it") } }launch { sharedFlow.collect { println("구독자2: $it") } }sharedFlow.emit("메시지") // 모든 구독자가 받음 replay 파라미터val sharedFlow = MutableSharedFlow(rep..
Flow 처리는 데이터 스트림을 변환, 필터링, 결합하는 등의 작업을 통해 원하는 형태로 가공하는 과정입니다. 이는 반응형 프로그래밍의 핵심 개념으로, 안드로이드 개발에서 UI 상태 관리나 데이터 처리에 매우 유용합니다.주요 Flow 처리 함수들1. map - 데이터 변환의 핵심map 함수는 Flow의 각 원소를 다른 값으로 변환할 때 사용하는 가장 기본적이면서도 중요한 연산자입니다. 원본 데이터를 유지하면서 새로운 형태의 데이터로 변환하는 역할을 합니다. suspend fun main() { flowOf(1, 2, 3) .map { it * it } // 각 원소를 제곱 .collect { print(it) } // 149} 동작 원리:상위 Flow에서 각 원소가 방출될..
Flow는 단순히 데이터를 변환하고 필터링하는 것을 넘어서, 생명주기의 각 단계에서 부가적인 작업을 수행할 수 있는 강력한 함수들을 제공합니다. 이러한 생명주기 함수들은 실제 안드로이드 개발에서 로깅, UI 상태 관리, 리소스 정리 등에 필수적으로 사용됩니다. onEach - 각 원소마다 부가 작업 실행onEach는 Flow의 각 원소가 방출될 때마다 지정된 함수를 실행하는 연산자입니다. kotlinsuspend fun main() { flowOf(1, 2, 3, 4) .onEach { println("Processing: $it") } .collect { println("Collected: $it") }} 출력:Processing: 1Collected: 1Process..
우리가 사용하는 대부분의 데이터 소스는 두 가지 종류로 구분이 가능하기 때문에 핫 스트림 데이터와 콜드 스트림 데이터의 차이를 이해하는 것이 소프트웨어적인 측면에서 상당히 유용함 핫콜드컬렉션 (List, Set)Sequence, StreamChannelFlow, RxJava 스트림 핫 vs 콜드Hot과 Cold 데이터 스트림의 차이는 아래와 같다. 핫 데이터 스트림데이터를 소비하는 것과 무관하게 원소를 생성항상 사용 가능한 상태이며, 여러 번 사용 되었을 때 결과를 다시 계산할 필요가 없음fun main() { val l = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .map { m(it) } // m1 m2 m3 m4 m5 m6 m7 m8 m..
코루틴 select코루틴은 가장 먼저 완료되는 코루틴의 결과를 기다리는 select 함수를 제공함 select 함수는 아래와 같이 활용될 수 있음여러 개의 채널 중 버퍼에 남은 공간이 있는 채널을 먼저 확인하여 데이터를 보내기이용 가능한 원소가 있는 채널로부터 데이터를 받을 수 있는지 여부 확인코루틴 사이에 경합을 일으키거나, 여러 개의 데이터 소스로부터 나오는 결괏값을 합치기 지연되는 값 선택하기여러 개의 소스에 데이터를 요청한 뒤, 가장 빠른 응답만 얻는 경우여러 개의 요청을 비동기 프로세스로 시작한 뒤, select 함수를 사용하는 방법으로 가능아래 코드는 하나의 비동기 작업이 완료됨과 동시에 결과값을 반환함suspend fun requestData1(): String { delay(100_0..
채널interface SendChannel { supsend fun send(element: E) fun close(): Boolean //...}interface ReceiverChannel { suspend fun receive(): E fun cancel(cause: CancellationException? = null) //...}interface Channel : SendChannel, ReceiveChannel SendChannel- 원소를 보내거나(또는 더하거나) 채널을 닫는 용도 ReceiveChannel- 원소를 받을 때(또는 꺼낼 때) 사용 두 인터페이스는 구분되어 있으며, 채널의 진입점을 제한하기 위해 ReceiveChannel이나 SendChannel..
동시성 문제에 대한 보호가 필요한 경우같은 시간에 두 개 이상의 스레드에서 호출되는 경우여러 스레드에서 값을 변경하려고 시도하면 동시성 문제가 발생할 수 있음 동시성 문제가 발생하는 예시두 개의 스레드가 똑같은 시간에 같은 수를 1씩 증가시킨다고 가정 (시작 값은 0)첫 번째 스레드가 현재 값(0)을 받고 난 후 프로세서가 두 번째 스레드로 전환두 번째 스레드에서도 현재 값(0)을 받고 1로 증가시킨 뒤 변수에 저장이후 다시 첫 번째 스레드로 다시 오게되면 멈췄을 때 사용한 0을 1로 증가시키고 저장이러한 경우 결과는 2가 아니라 1이 되어버림이런 경우 때문에 연산 일부가 반영되지 않는 결과가 발생 동시성 문제 해결 방법1. Synchronized 사용var counter = 0fun main() =..
안드로이드에서 스코프 만들기ViewModel의 viewModelScope를 사용하지 않는 경우에 대한 예시입니다.abstract class BaseViewModel : ViewModel() { protected val scope = CoroutineScope(Dispatchers.Main + Job()) override fun onCleared() { scope.cancel() }} 안드로이드는 메인 스레드에서 호출해야할 함수가 많으므로 기본 디스패처는 Main으로 설정 하였고, Scope 취소가 가능하도록 Job을 추가해주었습니다. 위의 코드에선 현재 onCleared() 시점에 scope 자체를 취소하고 있는 것을 볼 수 있습니다. 다만, 아래와 같은 상황에선 sc..