들어가기 전에본격적으로 프로젝트를 시작하기 전에 적절한 UI 갱신 및 리컴포지션 관리에 대해 관심이 생겼다. 이는 Compose에서 성능을 위해 필수적 요소라고 생각한다.. 나는 상태관리를 엉망으로 하고 있다는 걸 평소에 느꼈기 때문에 상태관리에 집중하고자 MVI 패턴을 공부하려 한다. (우연히 본 깃허브와 유튜브가 흥미를 돋게 한 것도 있다)MVI 패턴MVI 패턴은 Model, View, Intent로 크게 3가지 구성요소로 이루어져 있다. Model: UI에 반영될 상태 View: UI Intent : 사용자 액션, 시스템 이벤트에 따른 결과 (`android.content.Intent` 아님) M-V-I의 관계는 순수함수 형식으로 표현 가능한데, 단방향 흐름을 나타내고 있다. View에서 버튼 클릭..
동기화 블로킹멀티 스레딩, 멀티 프로세싱에서 중요한 것은 공유 상태 및 경쟁 상태이다. 다른 스레드에서 하나의 값을 수정, 조회할 때 서로 다른 값이 출력된다. 그래서 다음과 같은 코드에서는 예상하는 값이 나오지 않는다.suspend fun main(): Unit { var i = 0 coroutineScope { repeat(1_000_000) { launch { i++ } } } println(i) // ~998242} 자바에서 사용되는 `synchronized` 블록이나 동기화된 컬렉션을 사용해 해결할 수 있다. var i = 0fun main() = runBlocking { val lock = Any() re..
안드로이드에서 스코프 만들기대부분의 안드로이드 애플리케이션에는 MVC 모델을 기반으로 한 MVVM이나 MVP 아키텍처가 사용되고 있다. 이러한 아키텍처에서는 사용자에게 보여 주는 부분을 `ViewModels` 나 `Presenters`와 같은 객체로 추출한다. (일반적으로 코루틴이 가장 먼저 시작되는 객체)`UseCase` 나 `Repository`와 같은 다른 계층에서는 보통 중단 함수를 사용한다. 다음 코드는 `BaseViewModel`을 아래의 조건을 만족하여 만든 것이다.- 모든 뷰모델에서 쓰일 스코프를 단 한 번으로 정의- 메인 디스패처로 컨텍스트 정의- 스코프를 취소 가능하게 만들되, 스코프가 가지고 있는 자식 코루틴만 취소- 스코프에서 시작된 각각의 코루틴이 독립적으로 작동- 잡히지 않는 예..
기본 디스패처디스패처를 설정하지 않으면 기본적으로 설정되는 디스패처는 CPU 집약적인 연산을 수행하도록 설계된 `Dispatchers.Default`이다.이 디스패처는 코드가 실행되는 컴퓨터의 CPU 개수와 동일한 수(최소 두 개 이상)의 스레드 풀을 가지고 있다. CPU 집약적인 연산을 수행하며 블로킹이 일어나지 않는 환경 같이 스레드를 효율적으로 사용하고 있다고 가정하면 이론적으로는 최적의 스레드 수라고 할 수 있다.다음 코드를 통해 디스패처를 확인할 수 있다.suspend fun main(): Unit = coroutineScope { repeat(1_000) { launch(Dispatchers.Default) { List(1000) { Random...