실제 업무에서 발생했던 이벤트를 nowinandroid 프로젝트에 비유해서 표현하였습니다. tl;dr이미지 로더로 Coil 을 사용한다면, respectCacheHeaders 의 값을 서버 환경에 맞게 잘 설정해줘야 합니다.잘못될 경우, Disk 에 저장만하고, 사용하지 않고 있을 수도 있습니다.Glide 에 OkHttp 를 integration 해서 사용한다면 같은 문제가 발생할 수 있습니다. 동료가 Coil 을 이용해서 개발중, 이미지가 너무 늦게 보이는 것 같다는 이야기하였고 실제로 URL 형식의 이미지를 로드하는데, 특정 이미지의 경우 Disk Hit 이 되지 않고, 항상 Network Hit 이 되는 경우가 있었습니다. 다만 Glide 는 Disk Hit 이 잘 되고 있었습니다. (뒤에서 이야..
이따금식 LifecycleOnwer 를 사용하기 위해, View 의 확장함수인 findViewTreeLifecycleOwner 를 사용하는 경우가 있습니다. 간혹 아무 생각 없이 사용하다보면 findViewTreeLifecycleOwner 가 null 을 반환하는 경우가 있습니다. RecyclerView 에서 사용하는 케이스는 https://pluu.github.io/blog/android/2021/09/20/lifecycleowner/ 에서 잘 설명하고 있어서 해당 글을 참고 해도 좋을 것 같습니다. RecyclerView 에서는 doOnAttach 함수를 사용하여, Lifecycle 을 얻어올 수 있지만, doOnAttach 로 해결되지 않는 케이스들도 존재 합니다. 먼저 ViewTreeLifecyc..
TL;DR "네트워크 응답을 Result 와 같은 클래스로 래핑하면 실수할 확률이 높습니다." 상태 코드가 필요하면 awaitResponse 를 이용하고 아니라면 await 를 사용 합시다 해당 게시물은 실무에 도움이 되는 지식은 없고, 단순히 호기심으로 진행되었습니다. 회사에서 레거시 코드를 건드리는 중에, 신기한 일을 경험하였습니다. runCatching { apiCall.await() } .onSuccess { // ... } .onFailure { // ... } 와 같은 코드에서 네트워크 요청이 실패하여 400 이상 상태 코드들이 내려오는데 모두 onSuccess 를 타고 있었습니다. 문제가 있던 apiCall.await() 의 자료형은 아래와 같았습니다. apiCall 이 RxJava Sing..
히스토리를 찾아보니, Compose 를 현업에 처음 사용한 것이 작년 11월이네요. 주기적으로 밀도 있게 쓰지는 않았지만, 시간 될 때마다 조금식 기여하여 회사 프로젝트에 20 개 넘는 화면을 Compose 로 구성하였고, QDSC(Qanda-design-system-compose) Sample App 을 만들기도 하였습니다. QDSC 는 아직 완성 단계는 아니지만, 거의 마무리 단계인듯 보이네요. 앞으로 적을 글은 매우 주관적인 내용들을 담고 있습니다. 장점1 주관적으로 생각하는 Compose 의 가장 큰 장점을 하나만 선택하자면 "직관적" 이라고 말할 수 있을 것 같습니다. 선언형이기 때문에 컴포넌트(Box, Column, Row, Chip, Lazy* ...) 의 특성을 이해 한 뒤에 이를 나열하기..
해당 글은 주관적인 의견이 많이 들어가고, 잘못된 내용이 있을 수도 있습니다 :) 코드는 아래 링크로 첨부해두겠습니다 이번 주제는 서버에서 etag, last-modified 등의 캐시 처리를 지원해주지 않을 때, 안드로이드에서 간단히 처리할 수 있는 방법에 대해 알아보려고 합니다. *서버에서 캐시 처리를 위한 정보(Cache-Control) 를 잘 내려준다면, OkHttp 를 이용하여 CacheDirectory 만 생성해주면 알아서 처리해주기 때문에 해당 포스트를 읽지 않아도 됩니다. 먼저 안드로이드에서 캐시하면 가장 바로 떠오르는 것중 하나가 Room, sqlite, realm 과 같은 로컬 데이터 베이스를 사용하는 것 입니다. 해당 방식의 처리도 좋지만, Table 과 Entity 를 정의해야 한다..
해당 글에서는 AOSP 코드와 Material 코드를 보며 어떤식으로 에러를 수정하였는지 전달하고, 혹시나 AOSP 코드 등을 확인해야한다면 어떤식으로 접근할지 도움을 드리기 위해 작성하는 글입니다. 배포를 하기 위해 새로 개발된 Feature 들을 머지하고 QA 를 하던 도중 아래와 같은 에러가 발생하였습니다. MaterialCardView 에서 발생하고 있었고, 특징으로는 Android 9 이하의 버전들에서 발생하고 있었습니다. 먼저 사용하는 쪽의 코드를 간략하게 확인하였습니다. (checked 에 들어가는 값은 viewModel 을 통해 넣어주고 있고 회사 코드가 드러날 수 있어 제거하였습니다) 이전에 문제 없이 잘 동작했기 때문에 한눈에 어떤 것이 문제 인지 알수가 없었습니다. 또한 코드가 변경된..
Button(IconButton, RadioButton, Switch....) 대부분의 Component 에서 minimumTouchTargetSize() 함수가 내부에서 처리되는 것을 볼 수 있습니다. 잠시 함수를 보면, 48 dp 보다 작은 경우 Component 자체에 Padding 이 들어가게 됩니다(ContentPadding 을 0 으로 줘도 Component 밖으로 Padding 이 생깁니다). 따라서 48 보다 더 작은 값을 넣고 싶은 경우, 내부에 코드들을 모두 복사해서 minimumTouchTargetSize 함수를 제거해줘야 합니다. 혹은 아래와 같이 minimumTouchTargetEnforcement 를 false 로 변경하여 처리할 수도 있습니다. CompositionLocalPr..
회사 선임분에게 감사의 인사를 최근에 Compose 에서 viewModel 을 파라미터로 넘겨서 사용할 때, 편의를 위해 compositionLocalOf 메서드를 사용하여 같은 Composable Scope 안에서는 currentViewModel() 과 같이 호출하여 당시에 제공하는 Composable Scope 에 맞는 ViewModelStoreOwner 를 넣어주고 viewModel 을 사용할 수 있도록 구성하여 사용하고 있습니다. compositionLocalOf 를 사용할 때, Theme 등의 전파의 개념에만 사용하는 것을 구글 가이드에서는 추천하고 있기 때문에, Interface 형식(AAC 의 의존성도 제거할겸)으로 만들어 사용하고 있습니다. 별문제 없이 사용하다가, 특정 상황에서 curre..
몇일전 기능 구현후 테스트 하는 과정에서 Font 관련 함수에서 특정한 상황에 크래시가 나는 상황을 경험했습니다. 멋진 팀원들의 도움을 받아 어떤식으로 해결하였는지 공유합니다. 크게 1. 왜 크래시가 났는지? 2. 왜 간헐적으로 났는지? 3. 크래시가 나지 않았을 때는 어떤 클래스에서 이를 해소해주고 있었는지? 에 대한 내용으로 구성됩니다. 문제가 생긴 함수는 아래와 비슷한 식의 Font 의 id 를 가져와서 적용해주는 코드였습니다. // 예시 함수 fun TextView.setFont(@FontRes fontRes: Int) = apply { typeface = ResourcesCompat.getFont(context, fontRes) } 크래시 재현 상황은 앱 시작하자마자 특정 화면으로 이동하거나, ..