목록전체 글 (152)
시배's Android

MVI에 대해 생각할 때, 프로세스는 세 가지 핵심 개념으로 요약됩니다: 단방향 데이터 흐름 - 즉, 데이터가 한 방향으로 흐릅니다. Intent(의도) 처리는 논블로킹(non-blocking)입니다. 상태는 불변(immutable)합니다 - Model 외부에서는 변경할 수 없습니다(일반적으로 Android에서는 ViewModel 내부에서 처리됩니다). 개념적으로 MVI는 복잡하지 않으므로, 왜 직접 구현하는 대신 프레임워크를 사용해야 할까요? MVI 스타일의 프레임워크를 작성하는 것은 보다 복잡한 일입니다: - 기기 회전 및 프로세스 종료와 같은 라이프사이클 문제를 처리해야 합니다. - 다양한 쓰레딩 문제가 발생할 수 있습니다. - 멀티쓰레딩 코드와 함께 프레임워크에 대한 테스트를 작성해야 합니다. -..
fun Modifier.topFadingEdge( lazyListState : LazyListState, length : Dp, edgeColor : Color? = null ) = composed( debugInspectorInfo { name = "length" value = length } ){ val color = edgeColor ?: MaterialTheme.colorScheme.surface drawWithContent { val topFadingEdgeStrength by derivedStateOf { lazyListState.layoutInfo.run { val firstItem = visibleItemsInfo.first() when { visibleItemsInfo.size in 0...
채널의 이해 채널은 동시성 코드 간에 서로 안전한 통신을 할 수 있도록 해주는 도구다. 채널은 실행 중인 스레드에 상관없이 서로 다른 코루틴 간에 메시지를 안전하게 보내고 받기 위한 파이프라인으로 생각할 수 있다. 채널 유형과 배압 Channel의 send()는 일시 중단 함수다. 흔히 배압이라고 하며 리시버가 실제로 처리할 수 있는 것보다 더 많은 요소들로 채널이 넘치지 않도록 도와준다. 배압을 구성하기 위해 채널에 대한 버퍼를 정의할 수 있다. 채널을 통해 데이터를 보내는 코루틴은 채널 안의 요소가 버퍼 크기에 도달하면 일시 중단된다. 채널에서 요소가 제거되는 즉시, 송신자는 다시 재개된다. 언버퍼드 채널 버퍼가 없는 채널을 언버퍼드 채널이라고 한다. RendezvousChannel send()를 호..
Mavericks + Compose + Naver API Android 앱 개발에서 최신 기술인 Mavericks와 Compose를 활용하여 Naver API를 사용하여 책을 검색하는 앱을 구현해보겠습니다. MavericksState data class SearchUiState( val keyword: String = "", val books: Async = Uninitialized ) : MavericksState 책 검색 앱에서 사용할 SearchUiState 클래스는 Mavericks의 MavericksState 인터페이스를 구현합니다. 이 클래스는 책 검색 UI의 상태를 관리하고, 검색어 키워드와 검색 결과인 책 목록을 저장합니다. Async 클래스는 비동기 작업을 처리하기 위해 Mavericks..
Mavericks 매버릭스(Mavericks)는 Airbnb, Tonal 및 기타 대형 앱에서 사용되는 안드로이드 MVI 프레임워크로, 쉽게 배울 수 있으면서도 복잡한 플로우를 지원할만큼 강력합니다. 매버릭스를 만들 때 목표는 제품을 더 쉽고 빠르게, 더 재미있게 개발하는 것이었습니다. 우리는 매버릭스가 성공하기 위해 안드로이드 개발에 처음으로 참여하는 사람들에게도 쉽게 배울 수 있어야 하지만 Airbnb에서 가장 복잡한 화면도 지원할 수 있어야 한다고 믿습니다. 매버릭스는 Airbnb의 수백 개의 화면에서 사용되며, 새로운 화면의 100%에서 사용되고 있습니다. 또한 10억 개 이상의 다운로드를 가진 앱부터 작은 샘플 앱까지 무수히 많은 다른 앱에서도 채택되고 있습니다. 매버릭스는 Android Jet..

안드로이드 앱 개발에서 MVI (Model-View-Intent) 아키텍처는 현재 많은 개발자들에게 인기가 높아지고 있는 패턴입니다. MVI는 앱의 상태 관리와 UI 처리를 효과적으로 분리하여 앱의 유지보수성을 향상시키고, 디버깅과 테스트를 용이하게 만드는 장점을 가지고 있습니다. MVI 아키텍처란? MVI 아키텍처는 기존의 MVVM(Model-View-ViewModel) 패턴에서 발전된 아키텍처로, 상태 중심의 설계를 강조합니다. 앱의 상태를 하나의 단일 소스로 관리하고, 상태가 변경될 때마다 UI를 업데이트하는 방식을 채택합니다. MVI에서는 세 가지 주요 구성 요소가 있습니다. Model: 앱의 상태를 나타내는 데이터 모델입니다. 상태 변경에 따라 업데이트되며, 뷰와 독립적으로 존재합니다. View..
일시 중단 가능한 시퀀스 및 이터레이터 호출 사이에서 일시 중단되지만, 실행중에는 일시중단될 수 없다. 이로 인해 일시 중단 연산이 없어도 반복할 수 있다. 시퀀스와 이터레이터의 빌더는 CoroutineContext를 받지 않는다. 기본적으로 코드를 호출한 컨텍스트와 동일한 컨텐스트에서 코드가 실행됨을 의미한다. 정보 산출 후에만 일시 중지할 수 있다. 이를 위해서는 yield() 또는 yieldAll() 함수를 호출해야 한다. 이터레이터 인덱스로 요소를 검색할 수 없으므로 요소는 순서대로만 액세스할 수 있다. 더 많은 요소가 있는지 여부를 나타내는 hasNext() 함수가 있다. 요소는 한 방향으로만 검색할 수 있다. 이전 요소를 검색할 방법은 없다. 재설정 할 수 없으므로 한 번만 반복할 수 있다. ..

val context = LocalContext.current val activity = context as AppCompatActivity 일반적으로 compose에서 activity가 필요로 할 경우 위와 같은 코드를 통해 가져올 수 있습니다. 하지만 Hilt가 적용되어 있을 경우 이 부분에서는 크래시가 발생하였고 FragmentContextWrapper를 Activity로 변환할 수 없다는 내용이었습니다. FragmentContextWrapper 클래스는 ContextWrapper를 상속받고 있었고, HIlt 내부에서 사용하는 ViewComponentManager에서 관리되고 있었습니다. 해결 방법은 FragmentComponentManager 클래스의 findActivity 메서드를 이용하는 것입..