XML UIViewUI를 구성하는 가장 작은 단위를 말한다. 예를 들면 TextView, ImageView, Button 등이 있다.ViewGroupView를 여러 개 포함할 수 있는 컨테이너 개념이다. 예를 들면 LinearLayout, ConstraintLayout 등이 있다.ViewGroup 자체도 View의 일종이지만, 자식 View들의 Measure, Layout을 담당한다.View Tree 구조다음과 같이 XML으로 구성된 화면은 내부적으로 트리 구조로 이루어져 있다. 이 트리는 단순히 XML → 화면에 그려짐 처럼 동작하지 않는다. 그럼 어떻게 이 XML 코드가 View로 변경되고 화면에 그려질까?XML이 View 객체가 되는 과정XML은 UI를 정의하는 설계 파일이다. 이 XM..
작동 방식HiltHilt는 컴파일 타임에 KAPT/KSP를 통해 어노테이션을 분석한다.MetroMetro는 코틀린 플러그인 컴파일러 시점의 FIR 단계에서 어노테이션을 분석한다.FIR 단계는 IDE에서도 실행되기 때문에 실시간 오류 표시가 가능하고, 컴파일러가 내장되어 있기 때문에 별도의 추가 프로세서 호출이 필요 없어서 KAPT/KSP 보다 빠른 컴파일 속도를 제공한다. 하지만 Metro는 JAVA를 지원하지 않는다.DI 그래프 정의Hilt@HiltAndroidApp 어노테이션을 사용해 Application class에서 전역 그래프를 생성하며, 애플리케이션 시작 시점에 전역 그래프를 생성한다. 애플리케이션이 초기화 되는 시점에 그래프가 생성되므로 제어권은 프레임워크가 갖는다.@HiltAndroidAp..
ColdFlow콜드 플로우는 구독을 하면 데이터가 계속 흐르는 파이프이다. 따라서 누군가 collect()를 호출 즉, 구독을 해야 받을 수 있다. 콜드 플로우는 구독을 시작해야 emit이 가능하다.Flow콜드 플로우이다.Flow는 Coroutines의 일부분으로, 비동기 데이터 스트림을 처리하는 API이다. Flow는 소비자가 구독을 하면 데이터 생산이 시작되며, 이는 메모리 효율성을 높여준다는 장점이 있다. 비동기로 처리하게 되면 UI를 차단하지 않고 효율적으로 업데이트가 가능하다는 장점이 있다.HotFlow핫 플로우는 구독자가 있든 없든 이미 데이터가 흐르고 있는 파이프이다. 즉, 구독자가 있던 없던 emit을 통해 값을 계속 발행할 수 있다.대표적인 예로는 StateFlow와 SharedFlow가..
ViewModel 자동 DI1. 키생성@MapKey@Target(AnnotationTarget.CLASS)@Retention(AnnotationRetention.RUNTIME)annotation class ViewModelKey( val value: KClass,)다음과 같이 ViewModelKey 어노테이션 클래스를 생성한다. 이 어노테이션을 ViewModel에 달아주면 해당 ViewModel이 밑의 코드에 있는 viewModelProviders에 저장할 키 값임을 명시하는 것이다.2. 커스텀 ViewModelFactory생성@ContributesBinding(AppScope::class)class MetroViewModelFactory @Inject constructor( private v..
👍 Lottie의 장점Lottie는 gif와 비교해서 여러 장점이 있다.1. 파일의 크기git는 프레임마다 전체 이미지를 저장하는 비트맵 기반 포맷이다. 하지만 Lottie는 Json 기반으로 구현된 애니메이션 파일이기 때문에 gif 파일보다 낮은 용량을 사용하게 된다.낮은 용량을 사용하는 것은 로딩 속도가 그만큼 빨라지기 때문에, 사용자 경험에 만족을 줄 수 있다.앱의 크기 측면에서도 용량이 적기 때문에 이득이다.2. 품질gif 파일은 해상도가 정해져있는 파일이기 때문에, 크기에 따라 품질이 크게 깨진다. 만약 큰 화면에서 gif 파일을 보여주게 된다면 화면이 깨져 보일 것이다.하지만 Lottie는 Json으로 되어있고 백터로 렌더링하기 때문에 해상도가 정해져있지 않다. 따라서 화질이 깨지지 않는다...
문제"명예의 전당"이라는 TV 프로그램에서는 매일 1명의 가수가 노래를 부르고, 시청자들의 문자 투표수로 가수에게 점수를 부여합니다. 매일 출연한 가수의 점수가 지금까지 출연 가수들의 점수 중 상위 k번째 이내이면 해당 가수의 점수를 명예의 전당이라는 목록에 올려 기념합니다. 즉 프로그램 시작 이후 초기에 k일까지는 모든 출연 가수의 점수가 명예의 전당에 오르게 됩니다. k일 다음부터는 출연 가수의 점수가 기존의 명예의 전당 목록의 k번째 순위의 가수 점수보다 더 높으면, 출연 가수의 점수가 명예의 전당에 오르게 되고 기존의 k번째 순위의 점수는 명예의 전당에서 내려오게 됩니다.이 프로그램에서는 매일 "명예의 전당"의 최하위 점수를 발표합니다. 예를 들어, k = 3이고, 7일 동안 진행된 가수의 점수가..
❓ViewModel의 생명주기는 왜 중요할까안드로이드 UI 컴포넌트는 생명주기에 따라 생성되고 파괴된다. 예를 들어 다크모드, 프로세스 강제 종료 후 복원, 화면 회전 같은 configuration change가 일어났을 때 생성→파괴→생성이 반복된다. 따라서 fragment나 activity 내부의 데이터는 모두 초기화된다.ViewModel은 activity나 fragment의 생명주기보다 한 단계 더 길게 유지된다. 따라서 해당 데이터를 유지하기 위해서는 ViewModel을 사용한다.🔁 ViewModel의 생명주기configuration change 대응왜 ViewModel은 activity나 Fragment에 인스턴스화했음에도 생명주기가 더 길까? 그 이유는 ViewModelStore에 있다. a..
Reflection리플렉션은 프로그램의 구조를 런타임에 살펴볼 수 있는 언어 및 라이브러리 기능들의 집합이다.Kotlin에서 함수와 속성은 일급 객체이며, 이들을 런타임에 조사할 수 있는 능력은 함수형 또는 리액티브 스타일 프로그래밍을 할 때 중요하다.JVM 의존성JVM 플랫폼에서, Kotlin 컴파일러에는 리플렉션 기능을 사용하기 위해 필요한 런타임 컴포넌트가 별도의 아티팩트(kotlin-reflect.jar)로 포함되어 있다. 이는 리플렉션 기능을 사용하지 않는 애플리케이션의 런타임 라이브러리 크기를 줄이기 위해서다.Gradle이나 Maven 프로젝트에서 리플렉션 사용하기dependencies { implementation(kotlin("reflect"))}기타Gradle이나 Maven을 사용하..
📱 Android의 UI 동작안드로이드의 UI 처리는 싱글 쓰레드 모델로 동작한다. 즉 메인 쓰레드가 아닌 다른 쓰레드에서 UI 관련 작업을 하면 안된다. 따라서 안드로이드에서는 메인쓰레드 = UI 쓰레드이다.❓왜 싱글 쓰레드일까?안드로이드 뿐만 아니라 ios, Swing 등 대부분 UI 프레임워크는 UI 쓰레드 하나만 사용한다. 그 이유는 동시 접근 문제를 방지하기 위해서이다. 1. Thread-Safe하지 않다.Button, TextView, RecyclerView 등 UI 요소는 멀티 쓰레드에서 동시에 접근하면 상태가 꼬이거나 앱이 크래시 날 수 있다.위 코드와 같이 두 개의 쓰레드에서 TextView의 값을 병렬적으로 동시에 바꾼하고 가정하면 어느 값이 최종적으로 표시될지 예측이 불가하다. 즉,..
🚨 문제 상황DataBinding을 사용하며 BindingAdapter를 통해 xml의 속성을 커스텀 하던 중 viewHolder에 데이터를 무한으로 바인딩하는 문제가 발생했다.👿 원인submitList() 호출 private fun setupObservers() { viewModel.faqUiState.observe(viewLifecycleOwner) { state -> when (state) { FAQUiState.InitialLoading -> {} FAQUiState.Refreshing -> {} is FAQUiState.Success -> { ..