전체 글 149

[Compose] XML처럼 TextField 쓰면 Compose에선 망해요

Compose에서 TextField로 입력할 때, 글자 하나 칠 때마다 뭔가 버벅임을 느꼈습니다.. 처음 Compose로 전환했을 때 XML에서 하던 습관대로OutlinedTextField( value = text, onValueChange = { text = it viewModel.search(it) // ❌ 글자 칠 때마다 API 호출 })이렇게 작성했는데… 텍스트 입력할 때마다 밀리는 느낌?,, 스크롤과 겹치면 거의 끊기는 수준까지 가더라고요. 원인은 recomposition....Compose는 상태가 바뀌면 해당 Composable이 다시 그려지니, TextField도 마찬가지였습니다,근데 onValueChange에서 상태 변경 + API 호출까지 ..

🤖 Compose 2025.05.16

[Compose] LazyColumn 성능을 위해

✅ LazyColumn이란?- Compose에서 RecyclerView를 대체하는 스크롤 가능한 Composable- 내부적으로 보이는 항목만 그림 (지연 로딩)- 데이터가 많아질수록 Recomposition에 주의 사용하면서 느낀 성능 관련 주의점 key 설정 필요- Recomposition의 기준 설정LazyColumn { items(list) { item -> Text(item.name) }}key를 설정하지 않으면 → Compose는 index를 기준으로 recomposition 설정 만약, 리스트에서 요소가 삽입, 삭제되면 → 순서 바뀌면서 다시 그려짐 (☠️ 성능 낭비)✅ 해결 방법:LazyColumn { items(list, key = { it.id }) { it..

🤖 Compose 2025.05.13

[Android / Compose] Compose Context

까먹기 전에 줍줍..🎯 XML vs Compose의 "생명주기 + context" 구조 차이 XML 기반Activity나 Fragment가 View를 직접 소유View는 Activity가 죽을 때 context도 같이 정리됨 → context를 View 내부에서 써도 큰 문제가 없다 즉, UI는 생명주기를 따라감 Compose 기반UI 자체가 "함수로 구성된 상태 기반 UI"상태에 따라 UI가 수시로 재구성(recomposition) 되기에 Activity와 느슨하게 연결됨그래서 UI 함수 내에서 context를 막 쓰면, 그 시점에 context가 유효하지 않을 수 있음 XML : context가 항상 Activity와 뷰 안에 있고, 생명주기를 같이 가져가니까 자유롭게 써도 괜찮았지만,Comp..

🤖 Compose 2025.05.11

[Android] Widget 사용해보기

위젯을 처음 사용해봤어서, 언젠가 쓸 날을 위해 정리해보도록 하겠습니다Widget- 홈 화면에 배치 하는 뷰 컴포넌트 (RemoteView 기반)- RemoteView이기에 일반 View처럼 직접 조작 불가 즉, 동적 뷰 생성이 불가하기 때문에 RecyclerView, ListView, Glide등이 사용 불가 ⚙️ Widget의 필수 구성 요소 AppWidgetProvider - 위젯 생명주기 관리widget_info.xml - 위젯 크기, 초기 레이아웃, 업데이트 주기, configureActivity 설정RemoteViews - 위젯 UI를 위한 뷰 생성 도구, 동적 뷰는 생성 불가능 ConfigureActivity - 위젯 추가 시 보여지는 Activity (widget_info.xml에서 선..

카테고리 없음 2025.04.26

[Android] WorkManager

WorkManager는 처음 사용해봐서 정리해두려고 함,, 🫠✅ WorkManager란?- Android Jetpack의 백그라운드 작업 처리 라이브러리네트워크 연결 상태, 충전 중 여부 등 다양한 제약 조건 설정 가능 언제 사용하면 좋을까 ?- 작업이 백그라운드에서도 꼭 실행돼야 할 때 (ex. 업로드 같은 동작)- 네트워크 활성화 / 충전 중 등 조건을 걸고 싶을 때 - 주기적으로 실행되어야 할 때 (ex. 하루에 한 번 데이터 전송 예약) 🛠 WorkManager 구성요소 Worker - 실제 작업을 정의한 클래스 즉, doWork() 구현- 작업 방식(동기 / 코루틴 / RxJava)에 따라 Worker는 Worker, CoroutineWorker, RxWorker 3가지 타입으로 나..

📱 Android 2025.04.18

[Android] 클린 아키텍처 적용 시 고민했던 3가지 의문점

새 프로젝트를 시작하며 새로운 디자인 패턴(MVI)를 적용하려고 하다보니, 클린 아키텍처에 대한 고심?이 필요했습니다 들었던 의문점들을 정리해보았어요 🥹 🔒 Q1. Repository는 화면을 따라가야 할까? 데이터 주체를 따라가야 할까? 🔑 A. Repository는 무조건 “데이터 주체” 기준으로 네이밍해야 함!❌ MainRepository, BookScreenRepository ✅ BookRepository, UserRepository:  Repository는 데이터 주체를 중심으로 만들어야 여러 화면에서 재사용 가능하고, 구조가 깔끔하게 유지  🔒 Q2. Repository는 domain 계층인데, 구현체는 왜 data에 있을까? 🔑 A. Repository의 정의는 도메인에 있고, 실제..

📱 Android 2025.04.12

[Android / RecyclerView] onCreateViewHolder vs onBindViewHolder: 클릭 리스너는 어디에 둘까?

🎯 RecyclerView 클릭 리스너, 어디서 설정하는 게 좋을까?저는 원래 RecyclerView의 Adapter에 리스너를 설정할 때, 자연스레 onBindViewHolder()에서 뷰홀더로 넣어주는 방식을 많이 사용했었는데, 이게 성능과 메모리에 좋지 않다는 걸 알게 되었습니다 ,,!  일단, 2개의 호출 시점이 중요했습니다 ! 🔁 호출 시점의 차이onCreateViewHolder()→ 새로운 뷰 홀더가 필요할 때 한 번만 호출🔄 onBindViewHolder()→ 뷰 홀더가 데이터와 바인딩될 때마다 반복적으로 호출 ⚠️  스크롤할 때마다 계속 호출됨 onBindViewHolder에서 리스너를 생성하게 된다면,스크롤할 때마다 새로운 리스너 객체가 만들어지기 때문에 메모리 사용량이 증가되고 G..

📱 Android 2025.04.07

[Kotlin] ifEmpty

아주 편한 인라인 함수가 있어서 부랴부랴 포스팅합니다 kotlin 버전 1.3 이상부터 사용가능해요 ifEmptyinline fun , R, R> C.ifEmpty(defaultValue: () -> R): Rinline fun , R, R> C.ifEmpty(defaultValue: () -> R): Rinline fun , R, R> M.ifEmpty(defaultValue: () -> R): R 만약 이 배열/컬렉션/맵이 비어 있지 않으면 이 배열/컬렉션/맵 을 반환하고, 비어 있으면 defaultValue 함수를 호출한 결과를 반환fun main() { val myArray: Array = arrayOf() val defaultValue = listOf(42) val resul..

💡 Kotlin 2025.03.31

[Android] LiveData - observeForever

안녕하세요 오늘은 liveData의 observeForever에 대해 알아보겠습니다  observeForever LiveData의 메서드로 LifecycleOwner가 아닐 때도 데이터를 관찰할 수 있도록 합니다  하지만 lifecycleOwner와 관계없이 데이터를 관찰할 수 있기에, 수동으로 해제하지 않으면 메모리 누수 위험성이 있습니다 해제해줄 땐 꼭 removeObserver를 호출해야 합니다 !  완전한 코드는 아니지만 대충 뉘앙스만 보자면,, 아래와 같은 형식으로요  override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.ac..

📱 Android 2025.03.21

[Compose] Compose의 성능 최적화 기법 - 상태 읽기 연기

상태 읽기 연기 - 상태를 직접적으로 읽지 않고, 대신 lambda 같이 상태를 간접적으로 참조하는 것을 의미  만약 상태를 직접적으로 읽는다면 (param으로 값을 받게되면) 값이 변경될때마다 recomposition 즉 Composition -> Layout -> Drawing을 거치게 되는데, param대신 lambda를 사용하면 UI의 상태나 데이터를 직접적으로 참조하지 않고, 함수의 결과를 사용하기 때문에  Layout -> Drawing 단계만 진행하게 된다!  composition 단계에서 ui 트리를 만드는데 많은 리소스가 사용되는데 이 단계를 건너뛸 수 있다는 것만으로도 리소스 낭비를 막을 수 있는 셈!

카테고리 없음 2025.02.23