목록전체 글 (99)
안드로이드 개발자 노트
변환 함수 Flow를 반환하는 함수들은 대부분 다른 Flow를 만들어내는 함수를 호출해 동작한다.예를 들어, 다음과 같은 서비스가 있다고 가정해본다.class ObserveAppointmentsService( private val appointmentRepository: AppointmentRepository) { fun observeAppointments(): Flow> = appointmentRepository .observeAppointments() .filterIsInstance() .map { it.appointments } .distinctUntilChanged() .ret..
공유플로우 공유플로우를 통해 메세지를 보내면 대기하고 있는 모든 코루틴이 수신하게 된다.suspend fun main(): Unit = coroutineScope { val mutableSharedFlow = MutableSharedFlow(replay = 0) // or MutableSharedFlow() launch { mutableSharedFlow.collect { println("#1 received $it") } } launch { mutableSharedFlow.collect { println("#2 received $it") } } delay(1000)..
플로우는 값이 흐르기 때문에 여러 가지 방법으로 변형하는 것도 가능하다.플로우 생성과 최종 연산 사이의 연산들을 플로우 처리(flow processing)라고 한다.이 포스팅에서 예제는 다이어그램을 사용하여 원소가 어떻게 바뀌는지 보여준다.수평선은 시간, 선 위의 원소는 각 시간마다 플로우에서 내보낸 값들이다.위쪽 선은 연산이 실행되기 전의 플로우를 나타내며, 아래쪽 선은 연산이 끝난 뒤의 플로우를 나타낸다. map map은 새로운 플로우를 생성한 뒤 변형된 원소들을 하나씩 내보낸다.inline fun Flow.map( transform: suspend (value: T) -> R): Flow = flow { collect { value -> emit(transform(value..
Flow에서는 완료, 예외, 시작 같은 이벤트도 데이터 스트림의 일부로 간주되어 감지하고 처리할 수 있다.플로우 생명주기 함수를 사용하여 이러한 모든 상태를 Flow 안에서 관리할 수 있다. onEach: Flow에서 방출된 각 데이터를 처리하는 함수onStart: Flow가 시작되기 전에 실행할 작업 정의onCompletion: Flow가 완료되거나 취소되었을 때 실행onEmpty: Flow가 데이터를 방출하지 않을 경우 실행catch: Flow에서 발생한 예외를 처리flowOn: Flow가 실행되는 코루틴 디스패처를 변경 onEach onEach 람다식은 중단 함수이며, 원소는 순서대로 처리된다.다음 예제처럼 onEach에 delay를 넣으면 각각의 값이 흐를 때마다 지연되게 된다.suspend fu..
원시 값을 가지는 플로우 플로우가 어떤 값을 가져야 하는지 정의하는 flowOf 함수는 listOf함수처럼 사용할 수 있다.suspend fun main() { flowOf(1, 2, 3, 4, 5) .collect { print(it) } // 12345}값이 없는 플로우가 필요한 경우도 있다.suspend fun main() { emptyFlow() .collect { print(it) } // (nothing)} 컨버터 asFlow 함수를 사용해서 Iterable, Iterator, Sequence를 Flow로 바꿀 수 있다.suspend fun main() { listOf(1, 2, 3, 4, 5) // or setOf(1, 2, 3, 4, 5..
코틀린 코루틴의 플로우는 생각하는 것보다 간단한 개념이며, 중간 가능한 람다식에 몇 가지 요소를 추가한 거라고 생각하면 된다. Flow 이해하기 간단한 람다식을 실제 플로우처럼 만들어보는 예제이다.먼저, 간단한 람다식이다.fun main() { val f: () -> Unit = { print("A") print("B") print("C") } f() // ABC f() // ABC}여기서 내부에 지연이 있는 람다식 suspend로 만들면 다음과 같다.suspend fun main() { val f: suspend () -> Unit = { print("A") delay(1000) print("B") ..
플로우(flow)는 비동기적으로 계산해야 할 값의 스트림을 나타낸다.flow 인터페이스 자체는 떠다니는 원소들은 모으는 역할을 하며, 플로우의 끝에 도달할 때까지 각 값을 처리하는 걸 의미한다(flow의 collect는 컬렉션의 foreach와 비슷).Flow의 유일한 멤버함수는 collect이며, Iterable과 Sequence와 비슷하다.interface Flow { suspend fun collect(collector: FlowCollector)}interface Iterable { operator fun iterator(): Iterator}interface Sequence { operator fun iterator(): Iterator} 플로우와 값들을 나타내는 다른 방법들의..
핫 데이터 스트림: 데이터를 지속적으로 발행하며 구독자가 공유하는 실시간 스트림이다. 과거 데이터를 놓칠 가능성이 있지만, 실시간성을 요구하는 상황에 적합하다.콜드 데이터 스트림: 구독자마다 독립적인 데이터 흐름을 생성하여 항상 처음부터 데이터를 제공하며, 비동기 작업이나 기록된 데이터를 처리하는 데 유용하다. 핫 채널, 콜드 플로우 플로우는 다음과 같이 생성할 수 있다.val flow = flow { while (true) { val x = computeNextValue() emit(x) }}이는 채널을 생성하는 produce와 비슷한 형태의 빌더인 것을 알 수 있다.val channel = produce { while (true) { val x..
채널(Channel) 코루틴 채널(coroutine channel)은 비동기 프로그래밍에서 데이터를 코루틴 간의 통신을 위해 사용되는 구조이다. 채널은 송신자와 수신자의 수에 제한이 없으나, 채널의 양쪽 끝에 각각 하나의 코루틴만 있는 경우가 일반적이다.채널을 통해 전송된 모든 값은 단 한 번만 받을 수 있다.채널은 두 개의 인터페이스를 구현한 하나의 인터페이스이다.interface SendChannel { suspend fun send(element: E) fun close(): Boolean // ...}interface ReceiveChannel { suspend fun receive(): E fun cancel(cause: CancellationException?) ..
12.1. 단위 테스트 기초 12.1.1. 단위 테스트란 무엇인가? 단위(Unit): 명확히 정의된 역할의 범위를 갖는 코드의 집합으로, 정의된 동작을 실행하는 개별 함수나 클래스 또는 모듈이다.단위 테스트(Unit Test): 단위에 대한 자동화된 테스트를 작성하고 실행하는 프로세스를 말한다.객체 지향 프로그래밍에서 테스트 대상이 되는 단위는 주로 객체이며, 테스트 대상이 된 객체의 함수를 호출하고 함수가 호출되면 객체가 예상대로 동작하는지 확인하는 과정을 통해 테스트를 진행할 수 있다. 12.1.2. 테스트 환경 설정하기 dependencies { ... // JUnit5 테스트 프레임웍 testImplementation("org.junit.jupiter:junit-jupiter-ap..