Android/Today I Learned

Android/Today I Learned

findViewTreeLifecycleOwner == null 인 경우?

이따금식 LifecycleOnwer 를 사용하기 위해, View 의 확장함수인 findViewTreeLifecycleOwner 를 사용하는 경우가 있습니다. 간혹 아무 생각 없이 사용하다보면 findViewTreeLifecycleOwner 가 null 을 반환하는 경우가 있습니다. RecyclerView 에서 사용하는 케이스는 https://pluu.github.io/blog/android/2021/09/20/lifecycleowner/ 에서 잘 설명하고 있어서 해당 글을 참고 해도 좋을 것 같습니다. RecyclerView 에서는 doOnAttach 함수를 사용하여, Lifecycle 을 얻어올 수 있지만, doOnAttach 로 해결되지 않는 케이스들도 존재 합니다. 먼저 ViewTreeLifecyc..

Android/Today I Learned

네트워크 요청 실패했는데, RunCatching onSuccess 가 호출?

TL;DR "네트워크 응답을 Result 와 같은 클래스로 래핑하면 실수할 확률이 높습니다." 상태 코드가 필요하면 awaitResponse 를 이용하고 아니라면 await 를 사용 합시다 해당 게시물은 실무에 도움이 되는 지식은 없고, 단순히 호기심으로 진행되었습니다. 회사에서 레거시 코드를 건드리는 중에, 신기한 일을 경험하였습니다. runCatching { apiCall.await() } .onSuccess { // ... } .onFailure { // ... } 와 같은 코드에서 네트워크 요청이 실패하여 400 이상 상태 코드들이 내려오는데 모두 onSuccess 를 타고 있었습니다. 문제가 있던 apiCall.await() 의 자료형은 아래와 같았습니다. apiCall 이 RxJava Sing..

Android/Today I Learned

주관적인 Compose 사용 후기

히스토리를 찾아보니, Compose 를 현업에 처음 사용한 것이 작년 11월이네요. 주기적으로 밀도 있게 쓰지는 않았지만, 시간 될 때마다 조금식 기여하여 회사 프로젝트에 20 개 넘는 화면을 Compose 로 구성하였고, QDSC(Qanda-design-system-compose) Sample App 을 만들기도 하였습니다. QDSC 는 아직 완성 단계는 아니지만, 거의 마무리 단계인듯 보이네요. 앞으로 적을 글은 매우 주관적인 내용들을 담고 있습니다. 장점1 주관적으로 생각하는 Compose 의 가장 큰 장점을 하나만 선택하자면 "직관적" 이라고 말할 수 있을 것 같습니다. 선언형이기 때문에 컴포넌트(Box, Column, Row, Chip, Lazy* ...) 의 특성을 이해 한 뒤에 이를 나열하기..

Android/Today I Learned

서버 디펜던시 없이 네트워크 작업 캐시 구현하기(feat.OkHttp)

해당 글은 주관적인 의견이 많이 들어가고, 잘못된 내용이 있을 수도 있습니다 :) 코드는 아래 링크로 첨부해두겠습니다 이번 주제는 서버에서 etag, last-modified 등의 캐시 처리를 지원해주지 않을 때, 안드로이드에서 간단히 처리할 수 있는 방법에 대해 알아보려고 합니다. *서버에서 캐시 처리를 위한 정보(Cache-Control) 를 잘 내려준다면, OkHttp 를 이용하여 CacheDirectory 만 생성해주면 알아서 처리해주기 때문에 해당 포스트를 읽지 않아도 됩니다. 먼저 안드로이드에서 캐시하면 가장 바로 떠오르는 것중 하나가 Room, sqlite, realm 과 같은 로컬 데이터 베이스를 사용하는 것 입니다. 해당 방식의 처리도 좋지만, Table 과 Entity 를 정의해야 한다..

Android/Today I Learned

Material library 1.5.0 로 올리니 크래시가?!

해당 글에서는 AOSP 코드와 Material 코드를 보며 어떤식으로 에러를 수정하였는지 전달하고, 혹시나 AOSP 코드 등을 확인해야한다면 어떤식으로 접근할지 도움을 드리기 위해 작성하는 글입니다. 배포를 하기 위해 새로 개발된 Feature 들을 머지하고 QA 를 하던 도중 아래와 같은 에러가 발생하였습니다. MaterialCardView 에서 발생하고 있었고, 특징으로는 Android 9 이하의 버전들에서 발생하고 있었습니다. 먼저 사용하는 쪽의 코드를 간략하게 확인하였습니다. (checked 에 들어가는 값은 viewModel 을 통해 넣어주고 있고 회사 코드가 드러날 수 있어 제거하였습니다) 이전에 문제 없이 잘 동작했기 때문에 한눈에 어떤 것이 문제 인지 알수가 없었습니다. 또한 코드가 변경된..

Android/Today I Learned

Compose 버튼 사이즈 관련 Tips

Button(IconButton, RadioButton, Switch....) 대부분의 Component 에서 minimumTouchTargetSize() 함수가 내부에서 처리되는 것을 볼 수 있습니다. 잠시 함수를 보면, 48 dp 보다 작은 경우 Component 자체에 Padding 이 들어가게 됩니다(ContentPadding 을 0 으로 줘도 Component 밖으로 Padding 이 생깁니다). 따라서 48 보다 더 작은 값을 넣고 싶은 경우, 내부에 코드들을 모두 복사해서 minimumTouchTargetSize 함수를 제거해줘야 합니다. 혹은 아래와 같이 minimumTouchTargetEnforcement 를 false 로 변경하여 처리할 수도 있습니다. CompositionLocalPr..

Android/Today I Learned

Compose Navigation - viewmodel 사용할 때 주의할 점

회사 선임분에게 감사의 인사를 최근에 Compose 에서 viewModel 을 파라미터로 넘겨서 사용할 때, 편의를 위해 compositionLocalOf 메서드를 사용하여 같은 Composable Scope 안에서는 currentViewModel() 과 같이 호출하여 당시에 제공하는 Composable Scope 에 맞는 ViewModelStoreOwner 를 넣어주고 viewModel 을 사용할 수 있도록 구성하여 사용하고 있습니다. compositionLocalOf 를 사용할 때, Theme 등의 전파의 개념에만 사용하는 것을 구글 가이드에서는 추천하고 있기 때문에, Interface 형식(AAC 의 의존성도 제거할겸)으로 만들어 사용하고 있습니다. 별문제 없이 사용하다가, 특정 상황에서 curre..

Android/Today I Learned

Android Font 고군분투기

몇일전 기능 구현후 테스트 하는 과정에서 Font 관련 함수에서 특정한 상황에 크래시가 나는 상황을 경험했습니다. 멋진 팀원들의 도움을 받아 어떤식으로 해결하였는지 공유합니다. 크게 1. 왜 크래시가 났는지? 2. 왜 간헐적으로 났는지? 3. 크래시가 나지 않았을 때는 어떤 클래스에서 이를 해소해주고 있었는지? 에 대한 내용으로 구성됩니다. 문제가 생긴 함수는 아래와 비슷한 식의 Font 의 id 를 가져와서 적용해주는 코드였습니다. // 예시 함수 fun TextView.setFont(@FontRes fontRes: Int) = apply { typeface = ResourcesCompat.getFont(context, fontRes) } 크래시 재현 상황은 앱 시작하자마자 특정 화면으로 이동하거나, ..

Android/Today I Learned

Coil 로 OnDemand-image-resizing 적용하기

중요) 본 글은 원하는 사이즈를 보냈을 때 리사이즈 해주는 서버가 필요합니다. 이전에 회사에서 Glide -> Coil 로 마이그레이션 작업을 진행하면서 경험한 내용으로 이미지 사이즈에만 중점을 두고 있습니다. 또한 기승전결이 부족하고 도움이 되지 않을 수도 있습니다. OnDemand image resizing 이란 ? - 클라이언트의 요청에 따라 리사이징 된 이미지가 제공 되는 것을 의미합니다. 일단은 Coil 라이브러리내에서 사이즈 관련하여, 이미지를 효율적으로 로드하기 위한 방법이 존재하기 때문에 이부분을 먼저 보고 가겠습니다. sizeResolver 부분이 이미지를 로드할 때, 사이즈를 결정하는 부분입니다. 따로 명시적으로 처리하지 않으면, resolveSizeResolver() 함수가 불리우게 ..

Nanamare
'Android/Today I Learned' 카테고리의 글 목록