전체 글 151

입사 3개월차의 회고록

🕰 어느덧 3개월차...?정말 정신없이 입사해서 여유가 하나도 없었는데, 어느덧 입사한 지 3개월..! 처음엔 모르겠는 것들 투성이였는데, 이제야 조금 적응해가고 있다는 느낌 ㅎㅅㅎ그래서 한번,그동안의 기록을 남겨보려고 합니다 ✍️ 🧩 내가 새롭게 해본 것들입사하고 나서 실무에서 처음으로 다뤄본 기술들이 많았어요 역시 배움에 끝이란 없다.. Jetpack Compose SDK 멀티모듈자동화 스크립트안드로이드 위젯InstallReferrerNotification에 다양한 스타일 입혀보기하나하나 처음엔 어렵고 걱정이 너무 앞섰지만,지금은 “아! 그건 내가 해봤어” 라고 말할 수 있을 정도 !?👶🏻 → 👩🏻‍💻 으로 성장 중,,,,그래도 처음이란 두려움보다 이제 그래 해보지 뭐! 라는 마인드..

카테고리 없음 2025.05.31

[Android] MVI 패턴, 이름을 왜이렇게 헷갈리게 지었어요?

💡 MVI란?MVI는 Model - View - Intent 여기서 말하는 Intent는 Android Intent가 아니라 !!!👉 “사용자의 의도(Intent)부터 상태(State) 변경까지 이어지는 흐름 전체”를 뜻하는 개념적인 용어,,❗️그러니까 MVI의 Intent ≠ UIEvent ≠ 안드로이드 Intent → 절대 헷갈리면 안된다.. MVI 흐름[사용자 행동 (UIEvent)]→ ViewModel이 받음→ 상태(UIState) 변경 or 효과(UIEffect) 발생→ View가 변화됨- 이 흐름의 출발점은 항상 UIEvent- 화면은 항상 UIState 하나로만 관리 🧩 자주 사용되는 타입들 🧠 UIState현재 화면의 상태 (ex. 키워드, 로딩 중, 결과 등)data clas..

📱 Android 2025.05.27

[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