전체 글 146

[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

[Compose] 의존성 주입 (Dependency Injection) (ft.hilt)

우선, 라이브러리 적용이 필요합니다 (dagger, hilt)[versions]//...daggerVersion = "2.48"hiltVersion = "1.2.0"retrofitVersion = "2.9.0"gsonVersion = "2.10.1"[libraries]//...dagger-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "daggerVersion" }hilt-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltVersion" }androidx-gson = { group = "com.googl..

🤖 Compose 2025.02.11

[Compose] 안정성 stability

안정성에 관해서도 가장 중요한 키워드는 Smart Recomposition 같아요  Smart Recomposition- composition 함수에서 사용되는 데이터가 변경된 데이터의 함수만 재호출 즉 일부분의 ui만 업데이트 - 성능 최적화  이 때 compose는 필요한 recomposition임을 어떻게 구분할까 ?  -> paramater로 구분 크게 3가지로 나눠본다면  Stable parameters - 변경 시 컴포지션에서 추적이 가능하기 때문에 smart recomposition이 가능 - 즉, 변경 사항이 없다면 compose는 skip Unstable parameters - 변경 시 컴포지션에서 추적이 불가 -> 데이터의 변경 사항의 유무와 관계 없이 무조건 Recomposition-..

🤖 Compose 2025.02.09

[Android] ViewPager2 감도 조절하기

viewpager2를 카드뷰처럼 넘기고 싶은데 너무 휙휙 돌아가지는 거 같아서 서치하다 찾은 방법이다  ViewPager2는 ViewPager와 다르게 RecyclerView를 기반이라 recyclerview내에 스크롤 감도를 조절하는 mTouchSlop을 변경하면 된다  fun ViewPager2.reduceDragSensitivity() { val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView") recyclerViewField.isAccessible = true val recyclerView = recyclerViewField.get(this) as RecyclerView val touchS..

📱 Android 2025.02.08