Coil 은 썸네일 기능을 따로 제공하지 않고 있습니다. 이때 사용해 볼 수 있는 확장 함수 입니다. fun ImageView.loadOriginalImage(originUrl: String, thumbnailUrl: String) { CoroutineScope(Dispatchers.Main.immediate).launch { val thumbnail = async(Dispatchers.IO) { val request = ImageRequest.Builder(context) .data(thumbnailUrl) .build() Coil.execute(request).drawable } val original = async(Dispatchers.IO) { val request = ImageRequest.Bu..
중요) 본 글은 원하는 사이즈를 보냈을 때 리사이즈 해주는 서버가 필요합니다. 이전에 회사에서 Glide -> Coil 로 마이그레이션 작업을 진행하면서 경험한 내용으로 이미지 사이즈에만 중점을 두고 있습니다. 또한 기승전결이 부족하고 도움이 되지 않을 수도 있습니다. OnDemand image resizing 이란 ? - 클라이언트의 요청에 따라 리사이징 된 이미지가 제공 되는 것을 의미합니다. 일단은 Coil 라이브러리내에서 사이즈 관련하여, 이미지를 효율적으로 로드하기 위한 방법이 존재하기 때문에 이부분을 먼저 보고 가겠습니다. sizeResolver 부분이 이미지를 로드할 때, 사이즈를 결정하는 부분입니다. 따로 명시적으로 처리하지 않으면, resolveSizeResolver() 함수가 불리우게 ..
몇일 전 회사에서 컴포즈와 코루틴의 성능을 최대화 시키기 위해 Glide 에서 Coil 로 Migration 하는 작업을 진행하였습니다. Glide 디펜던시를 모두 제거하고 이후에, Glide 에서 사용하는 Cache Directory 도 정리해주는 작업을 진행하였습니다. 따로 Cache Directory path 를 명시적으로 잡아서 사용하지 않고 있다면 아래 코드에서 Cache Directory path 를 찾을 수 있습니다. 따라서 아래와 같은 느낌으로 코드를 작성해주면 됩니다. // 경우에 따라서 workerThread, mainThread 골라서 사용하면 될 것 같습니다 val defaultGlideCacheName = "image_manager_disk_cache" context.cacheDi..
이전 글 : https://nanamare.tistory.com/170 와 관련이 있습니다. 몇일 전 아래와 같은 에러를 다시 만났습니다. Software rendering doesn't support hardware bitmaps 해당 이슈는 아래와 같은 코드에서 발생했습니다. canvas.drawBitmap(bitmap, width, height, paint); 결론적으로 "위 코드의 bitmap 이 하드웨어 비트맵이기 때문에, CPU 에 정보가 있지 않아 그려낼 수 없다." 가 원인이였는데, 이전글에서 bitmap 을 가져올 때, ALLOCATOR_SOFTWARE 옵션을 주기 때문에 아마 다른 원인이 있을 것이라고 생각하고 코드를 확인해봤습니다. uri 에서 bitmap 을 변환 시키는 것이 아닌 ..
ViewModel 의 라이프 사이클은 Activity 나 Fragment 보다 길기 때문에 ViewModel 에서 Fragment, Activity 에 콜백 받는 것은 실수를 유발합니다 (ViewModel 에서든) 라이브데이터나 플로우를 사용하여 관찰(observe) 혹은 수집(collect) 하는 것이 좋습니다. // Activity or Fragment.kt viewModel.loadItemList() { list -> // Activity 가 Destroy 상태거나 Fragment 인 경우 not Attached 일 수 있음 // 또한 isDestroyed 혹은 isAdd 와 같은 상태를 확인하는 처리가 필요하게 됩니다 adapter.submitData(list) }
몇일전 일을 하는 도중 아래와 같은 이슈를 만났습니다. Fatal Exception: java.lang.NullPointerException Missing required view with ID: com.{package}.debug:id/{resource_id} ViewBinding 을 사용하고 있는데, xxxxBinding 클래스에서 해당 아이디를 찾지못하는 이슈였습니다. 해당 레이아웃 파일에 들어가서 확인해보니, 아이디가 잘 선언되어 있고, ctrl + 클릭 조합으로도 리소스가 잘 이어져있는 것을 확인했습니다. 잠시 등에 땀이 흐를뻔했지만, 혹시나해서 같은 바인딩 클래스가 있는지 확인해봤습니다 . A 모듈에서 xxxxBinding 클래스가 사용되고 있었고, B 모듈에서도 xxxxBinding 클래스가..
먼저 1. Firebase console -> 설정 -> 내프로젝트 항목에서 지원 이메일이 제대로 등록되어있는지 체크하기 2. Firebase console -> 설정 -> 내 앱 항목에서 SHA-1 타입의 인증서가 잘 추가가 되어있는지 체크하기 3. Debug 앱 등이 있어도 BuildType 에 맞게 들어있다면 google-services.json 에 모두 담겨 오기 때문에 크게 문제 없습니다. 4. 이모든게 모두 잘 되어 있다면 Google 사용자 인증 정보에 들어가서 OAuth 2.0 클라이언트에 해당 앱의 패키지 혹은 디버그 버전 패키지가 잘 추가되어 있는지 확인 하기 저는 4번 케이스로 보통은 google 에서 자동으로 추가시켜주는데(키에 was created auto by google 식으로..
LiveData, Coroutine, Flow 를 이용한 반응형 UI - Part 1 LiveData, Coroutine, Flow 를 이용한 반응형 UI - Part 1 https://medium.com/androiddevelopers/livedata-with-coroutines-and-flow-part-i-reactive-uis-b20f676d25d7 LiveData with Coroutines and Flow — Part I: Reactive UIs This article is a summary of the t.. nanamare.tistory.com LiveData, Coroutine, Flow 를 이용한 반응형 UI - Part 2 LiveData, Coroutine, Flow 를 이용한 반응형..
LiveData, Coroutine, Flow 를 이용한 반응형 UI - Part 1 Jetpack 에서 제공하는 AAC 는 안드로이드 개발에 간편한 기능들을 제공합니다. 따라서 코루틴의 작업 및 취소(Jobs and cancellation)들에 대해서 걱정할 필요가 없습니다. 단순히 작업의 범위(scope of operation)를 잘 선택해주기만 하면 됩니다. 다양한 스코프에 대해 알아봅시다! ViewModel Scope 해당 스코프는 코루틴을 사용할 때 가장 많이 사용하는 스코프중 하나입니다. 보통 ViewModel 에서 데이터 관련한 작업들이 시작되기 때문입니다. 따라서 viewModelScope extension 을 사용하면, ViewModel 의 onCleared 메서드가 호출될 때 자동으로 ..