📱 Android 66

[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

[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

[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

[Android] AAC의 LiveData, ViewModel의 LiveData

AAC- 안드로이드 아키텍처 컴포넌트(Android Architecture Components)로 앱 개발을 더 쉽고 유지보수 가능하게 해주는 구성요소들의 모음 LiveData는 AAC의 일부로 아래와 같은 특성을 가진다Observer 패턴 기반의 데이터 홀더로, 데이터를 감싸고 UI와 연결할 수 있음.LifecycleOwner(Activity, Fragment 등)를 인식해, UI Controller가 종료되면 자동으로 Observer를 제거해 메모리 누수를 방지함 ViewModel에서 쓰느냐 Activity, Fragment에서 쓰느냐의 차이는 바로 lifecycle만약 ViewModel에서 사용하면 ViewModel의 Lifecycle을 따르기 때문에, 화면 회전 시에도 데이터가 유지즉 , View..

📱 Android 2025.02.04

[Android] binding 즉시 업데이트 하기 executePendingBindings

executePendingBindings- 뷰에 수정된 사항을 즉시 업데이트 하는 함수로, 바인딩을 즉시 실행하는 느낌이라고 보면 될 거 같아요  public void executePendingBindings() { if (mContainingBinding == null) { executeBindingsInternal(); } else { mContainingBinding.executePendingBindings(); } }  recyclerview가 재활용될 때  ViewHolder가 이전 데이터의 상태를 유지하고, 새로운 데이터가 바인딩될 때까지 잠시 이전 상태가 보이는 경우가 생길 수 있어요 이를 방지하기 위해 ..

📱 Android 2024.11.21

[Android] 이미지뷰에 apng 파일 적용하기

APNG는 애니메이션을 지원하는 PNG 파일 형식으로, GIF보다 더 나은 품질과 효율성을 제공하는 파일입니다 우선 대중적인 APNG4Android 라이브러리를 사용하겠습니다 https://github.com/penfeizhou/APNG4Android GitHub - penfeizhou/APNG4Android: Android animation support for APNG & Animated WebP & Gif & Animated AVIF, High performanceAndroid animation support for APNG & Animated WebP & Gif & Animated AVIF, High performance - penfeizhou/APNG4Androidgithub.com implem..

📱 Android 2024.11.17

[Android] Multipart / Presigned url

파일업로드 방식 2가지에 대해 알아보겠습니다 MultiPart- 여러 데이터 조각을 하나의 HTTP 요청으로 전송하는 방식- 안드로이드에서는 Retrofit, OkHttp 등의 라이브러리를 통해 쉽게 구현가능한데, 파일 업로드와 텍스트 데이터 전송에 주로 사용됩니다 MultiPart의 방식- 클라이언트 → 서버 : 클라이언트는 파일을 여러 부분으로 나누어 서버에 전송- 서버 → 저장소 : 서버는 클라이언트로 파일의 각 부분을 수신한 후, 이를 하나의 파일로 조합하여 저장소에 저장 @MultiPart annotation을 사용하면 돼요 interface ApiService { @Multipart @POST("upload") fun uploadFile( @Part file: Mu..

📱 Android 2024.11.14

[Android] 앱 배포 실패, 그 원인은 SoLoader ? (ft.giphy)

배포를 하려다가 플레이 콘솔에서 배포 실패가 떴었어요 에러 메시지는 아래와 같았습니다 하나 이상의 앱에 결함이 있는 SoLoader SDK 버전이 포함되어 있으므로 앱이 다운되어 사용성이 저하됩니다 64비트 전용 기기에서 비정상 종료를 일으키는 SoLoader SDK 버전이 앱에 통합되어있습니다 공식문서에도 친절하게 나와있습니다 :) https://support.google.com/googleplay/android-developer/answer/12576726?hl=ko 잘못된 SoLoader 버전이 있는 앱 수정하기 - Play Console 고객센터도움이 되었나요? 어떻게 하면 개선할 수 있을까요? 예아니요support.google.com 에러 수정방법 1️⃣ 앱이 SoLoader SDK에 직접 종속..

📱 Android 2024.10.11

[Android / Glide] Glide override / Glide 이미지 크기 조정

overrideoverride는 이미지의 크기를 강제로 지정하여 로드할 때 사용되는 메서드입니다우선 함수 원형을 보자면,paramater로 width, height을 받아서 크기를 조절해줍니다  @NonNull @CheckResult public T override(int width, int height) { if (isAutoCloneEnabled) { return clone().override(width, height); } this.overrideWidth = width; this.overrideHeight = height; fields |= OVERRIDE; return selfOrThrowIfLocked(); } 만약 width, height이 같..

📱 Android 2024.10.08