
요즘 오디를 Compose로 마이그레이션하고 있다.오디는 우아한테크코스에서 팀 프로젝트로 개발했던 앱인데,당시에는 Compose를 모르는 상태였기 때문에 모든 UI가 XML로 구현되어 있다.틈틈이 마이그레이션을 하는게 요즘 내 힐링이다. 코드가 간결해지는게 눈에 보여서 재밌다 ㅎ 오디의 주소 검색 화면은 Paging3을 사용해 무한 스크롤을 구현했었다.이 화면을 마이그레이션하며 "Compose에 Paging3를 어떻게 적용할지"에 대해 배운 것들을 정리해 보려고 한다. 이 글은 RecyclerView에서 Compose로 마이그레이션하는 방법을 중점적으로 다룬다.즉, Paging3와 PagingSource, PagingDataAdapter에 대한 내용을 자세히 다루지 않는다. 가장 먼저, Recycle..
그동안 Flow의 특성을 고려하지 않거나 가독성이 좋지 않은 상태로 "돌아가는 테스트 코드"를 작성했었다.그러다보니 내가 짠 테스트인데도 지금 다시 보니 어떤 코드인지 제대로 이해하지 못하는 경우가 꽤나 있었다.. 새로운 사이드 프로젝트를 시작하며, 가독성이 좋고 유지보수할 수 있는 테스트를 작성하려고 노력 중이다.그 과정에서 Turbine 라이브러리를 얕게 학습했는데, 오늘은 이와 관련된 포스팅을 하려고 한다. Turbine 라이브러리가 무엇인지 간단히 알아보고,Turbine를 사용한 Flow와 StateFlow, SharedFlow 테스트 방법을 각각 소개한다.Turbine를 사용하지 않았을 때의 코드와 비교하여 Turbine의 이점을 알아보려고 한다. Turbine 라이브러리란?https://gi..

Compose Side Effect 이해하기! (1)Side Effect란?컴포즈에서 Side Effect는 컴포저블 함수의 밖에서 발생하는 앱 상태에 대한 변경사항이다.예를 들어 사용자가 버튼을 클릭하면 다른 화면이 열리거나, 앱이 인터넷이 연결되어 있지 않thdbs523.tistory.com 저번 포스팅에서 Side Effect이 어떤 건지 알아보고, Side Effect와 관련된 컴포저블 함수 LaunchedEffect, DisposableEffect, SideEffect에 대해 알아봤다. rememberCoroutineScoperememberUpdatedStatederivedStateOfproduceStatecollectAsStateWithLifecyclesnapshotFlow이번엔 State를 ..
Side Effect란?컴포즈에서 Side Effect는 컴포저블 함수의 밖에서 발생하는 앱 상태에 대한 변경사항이다.예를 들어 사용자가 버튼을 클릭하면 다른 화면이 열리거나, 앱이 인터넷이 연결되어 있지 않을 때의 메시지 등이 될 수 있다. 기본적으로 컴포저블 함수는 Side Effect에 자유로워야 한다. 이때 자유로워야 한다는 말은, 컴포저블 함수를 트리거하기 위해서는 파라미터를 변경하거나 컴포저블을 재호출해야 한다는 뜻이다.컴포저블 내부에서 컴포저블 외부에 있는 변수나 동작에 영향을 주도록 설계해서는 안 된다.하나의 컴포저블에 대해 리컴포지션이 여러번 발생할 수 있고, 여러 스레드에서 호출될 수 있기 때문이다. Side Effect를 이해하고 잘 활용하기 위해, 관련된 컴포저블 함수를 알아보려고 ..
우리가 사용하는 대부분의 데이터 소스는 핫 스트림 데이터와 콜드 스트림 데이터 두 가지로 구분할 수 있다.즉, 이 두 가지의 차이를 이해하는 것이 중요하다.핫콜드컬렉션(List, Set)Sequence, StreamChannelFLow, Rx.Java 스트림(List, Set과 같은) 컬렉션은 핫이고, Sequence와 자바의 Stream은 콜드다.Channel은 핫이고, Flow와 (Observable, Single과 같은) Rxlava 스트림은 콜드다. 핫 vs 콜드핫 데이터 스트림은 열정적이라 데이터를 소비하는 것과 무관하게 원소를 생성한다.반면에 콜드 데이터 스트림은 게을러서 요청이 있을 때만 작업을 수행하며, 아무것도 저장하지 않는다. fun main() { val l = buildLis..
코루틴에는 select 함수가 있다. 이 select 함수는 가장 먼저 완료되는 코루틴의 결과를 기다리는 역할을 한다.또한 여러 개의 채널 중 남은 공간이 있는 채널에 데이터를 보내거나, 여러 개의 채널 중 원소가 존재하는 채널로부터 원소를 받을 수도 있다.코루틴 사이에 경합을 일으키거나, 여러 개의 데이터 소스로부터 나오는 결괏값을 합칠 수도 있다. select 함수는 코틀린 코루틴이 출시된 이후부터 사용이 가능했지만, 아직 실험용이다. 즉, API 형태가 바뀔 가능성이 있다.select를 실제로 사용하는 경우가 드물기 때문에, 안정화될 가능성도 적다. 지연되는 값 선택하기여러 개의 소스에 데이터를 요청한 뒤, 가장 빠른 응답만 얻는 경우를 생각해 보자.가장 쉬운 방법은 요청을 여러 개의 비동기 프..

채널은 코루틴끼리의 통신하기 위한 기본적인 방법이다.채널은 공공 도서관으로 비유할 수 있다. 하나의 책을 찾으려면, 책을 빌렸던 사람이 다시 반납해야 한다.이는 채널이 작동하는 방식과 비슷하다.채널은 송신자와 수신자의 수에 제한이 없고, 채널을 통해 전송된 모든 값은 단 한 번만 받을 수 있다. interface SendChannel { suspend fun send(element: E) fun close(): Boolean // ...}interface ReceiveChannel { suspend fun receive(): E fun cancel(cause: CancellationException? = null) // ...}interface Channel : SendC..
UnconfinedTestDispatcherfun main() { CoroutineScope(StandardTestDispatcher()).launch { print("A") delay(1) print("B") } CoroutineScope(UnconfinedTestDispatcher()).launch { print("C") delay(1) print("D") }}C테스트 디스패처는 StandardTestDispatcher 외에 UnconfinedTestDispatcher도 있다. StandardTestDispatcher는 스케줄러를 사용하기 전까지 어떤 연산도 수행하지 않는다.반면에 UnconfinedTes..