안드로이드 89

[Android] IllegalStateException: Method addObserver must be called on the main thread

문제발생 IllegalStateException: Method addObserver must be called on the main thread ViewModel을 가지고 뭔가 하려했을때 해당 오류가 발생하는 경우가 있다. 이것은 ViewModel을 lazy init해서 사용할 시에 발생하게 되는데, 나의 경우에는 아래와 같은 코드에서 발생했다. private val splashViewModel by viewModels() override fun onStart() { super.onStart() lifecycleScope.launch(Dispatchers.IO) { splashViewModel.doSomething() } } 원인 처음에는 "무슨 소리야 옵저버같은거 안붙였는데"라고 반발이 올라왔지만, 컴..

[안드로이드] Airbnb Epoxy 라이브러리 놓치기 쉬운 부분들

개발중인 앱에서 RecyclerView는 Epoxy를 사용하고 있는데 상당히 편리함을 누렸지만 제대로 알지못하고 있는거 같아서 공식문서를 쭉 훑어보았다. 이번 글에서는 공식 문서와 소개 페이지에서 설명하고 있는 요소들 중에서 놓치기 쉬웠던 부분들 몇가지를 체크하려한다. EpoxyAttribute EpoxyAttribute를 사용하면 자동 Diffing에 사용되는 hashCode()나 equals() 같은 메소드가 생성되는데, 이를 원하지 않는다면 @EpoxyAttribute(hash=false) 로 꺼둘 수 있다. 클릭 리스너처럼 매번 bind 될때마다 재생성되는 필드들에 적용하면 좋다. Hiding Models View가 조건부로 보여지고 숨겨져야할때 사용할 수 있다. model.show(boolean..

안드로이드 Unity 플러그인 만들기

회사에서 GoogleAnalaytics나 AppsFlyer처럼 게임 중 발생하는 이벤트들을 캐치해서 보내는 SDK를 개발할 일이 생겼는데, Native를 왠만하면 이용하지 않는 편으로 구현하려했으나 최종 코드 가독성이라던가 파일 관리, 추상화 등의 이유로 Native를 사용하기로 했다. 오늘은 그때를 돌아보며 귀찮지만...처음 연결했던 방법을 적어보려한다. 1. classes.jar 추출하기 이번이 나의 처음 SDK 개발이었으며, Unity조차도 잘 몰랐다. 처음엔 Unity와 Android가 어떻게 소통한다는거지? 부터 이해가 필요했다. 둘 사이의 소통을 위해, Unity 라이브러리가 존재한다. 일반적으로는 아래 경로들에 위치하며, 이름은 classes.jar다. 이 파일을 복사하여 어딘가에 저장해두자..

[Android Studio] 범블비 Network Inspector 인코딩 깨짐 해결방법

안드로이드 스튜디오 범블비(Bumblebee) 버전으로 업데이트하니 원래 잘 나오던 Network Inspector에서의 응답 글자 인코딩이 깨져보였다. 해결방법 해결방법은 Retrofit Request Header에 Accept-Encoding을 추가해주면된다. Accept-Encoding: identity; 이는 클라이언트가 지원하는 인코딩을 서버에 알려주는 것인데, identity의 경우 압축이나 수정없이 어떠한 인코딩도 수행되지 않음을 의미한다. 실제 프로덕션에서는 gzip 인코딩등 압축을 이용할 수 있기때문에 Debug 모드일때만 Accept-Encoding을 identity;로 바꿔주도록 조건문을 추가하는 것이 좋다. 1. 개별 API에 추가하는 방법 @Headers("Accept-Encodi..

[안드로이드] BottomSheetBehavior로 차이 카드 앱 처럼 UI 구성하기

어? 이거 좋다! 차이카드에는 올려서 부스트하기 기능이있다. 아래에서부터 핸들을 쭉 땅겨서 부스트가 작동하도록하는 것인데... 플레이오에서 레벨업 페이지와 내역페이지가 리스트로 죽 늘어진 레이아웃을 보고...차이처럼 구성해보는 것은 어떨까 건의드렸다. 성능상의 문제가 있기도 했지만, 작은 폰을 쓰는 유저들은 아래에 내역이 있는지 조차 모를 확률도 있었다. (ㅋㅋㅋ) 호기롭게 건의했지만 혼자서 공부하다보니 저런 레이아웃이 어떻게 구현되어있고, 뭐라고 검색해야 할지도 몰랐는데 해답은~ BottomSheet이었다. 그동안 BottomSheet은 BottomSheetDialog로만 이용해봐서 일반 뷰에서 쓰는건 처음이었는데, behavior만 설정해주면 간단히 멋진 레이아웃을 구현할 수 있었다. 다음 화면과 같..

[Okhttp3] Expected URL scheme 'http' or 'https' but no colon was found 해결방법

Fatal Exception: java.lang.IllegalArgumentException Expected URL scheme 'http' or 'https' but no colon was found okhttp3.HttpUrl$Builder.parse$okhttp (HttpUrl.java:1260) okhttp3.HttpUrl$Companion.get (HttpUrl.java:1633) okhttp3.Request$Builder.url (Request.java:184) okhttp3.Cache$Entry.response (Cache.java:641) okhttp3.Cache.get$okhttp (Cache.java:183) okhttp3.internal.cache.CacheInterceptor.int..

[안드로이드] Koin에서 Hilt로, Hilt 배워보기

단지 쉽다는 이유만으로 Koin 라이브러리를 사용하고 있었는데 최근 앱의 리팩토링 고민을 하면서, 다른 프로젝트 코드들을 읽어보다가 내가 Hilt에 대해서 너무 모르는거 아닌가라는 생각이 들었다. 참고자료에 있는 Droid Knights 2020 영상에 따르면 상위 10,000개의 안드로이드 앱 중 74%가 Dagger를 사용하고 있다고 한다... github에 올라온 많은 프로젝트들도 Dagger/Hilt를 사용하고있으니 이번기회에 확실히 짚고 넘어가면 좋을 것 같다. Koin의 특징 Koin은 확실히 쉽다. Hilt가 쉬워졌다고 하지만 Koin급은 아니다. 그리고 어노테이션을 사용하지 않고 Stub 파일을 만들지 않기 때문에 빌드 시간이 빠르다. 하지만 런타임에 바이트 코드를 생성하기 때문에 Hilt..

[안드로이드] 카카오웹툰 앱에서 쓴 오픈소스 라이브러리를 알아보자

카카오 웹툰이 처음 나왔을때, 나도 부정적인 시선으로 보는 사람들 중에 하나였다. 웹툰을 보지는 않지만 예전에 웹툰을 봤을때 요일별로 나눠져있는게 그야말로 정석이었고, 앱을 켤때도 [O요일 웹툰 봐야지!] 라는 생각으로 켜곤했다. 하지만 카카오 웹툰은 그 정석과는 다른 방향으로 개발되었다. AI 추천 웹툰이 먼저고, 요일별 웹툰은 조금 더 숨겨져있다. 새로운 것에대한 거부감일지, 정말로 유저가 원하는 것과 맞지 않아서일지는 조금 더 두고보면 알겠지만, 개발자로서 카카오 웹툰의 혁신적인 UI/UX는 분명 엄청났다! 가장 궁금한건 역시 "어떻게 만들었을까"다. 카카오 웹툰을 다운받아서 APK 파일을 추출 후 압축을 해제하면 사용한 에셋들이 나온다. 그중에서 oss_notice.html이라는 카카오 웹툰 앱을..

[안드로이드] Jetpack Compose 테마와 스타일 정의하기

Jetpack Compose를 시작하기 위한 강의는 구글에서 제공한다. 레이아웃을 어떻게 만들지는 한 번만 따라해도 어느정도 각이 나온다. 어떻게 디자인하는지 알려주는 강의는 너무 많다. 하지만 중요한건 Integration! 앞으로 블로그에서 다룰 Jetpack Compose 관련 주제가 바로 Integration이 될 것이다. 어떻게 내 프로젝트에 통합시킬 수 있을지! Theming 그 첫번째로 테마(Theme)와 스타일에 관해서 알아보려고한다. Jetpack Compose에서 아주 쉽게 Material Design을 적용시킬 수 있다고는 하지만, 디자이너들은(93% 확률로 아이폰을 이용중) 우리에게 Material Design을 던져주지 않는다. 앱 고유의 스타일을 어떻게 확립하고 적용시킬 수 있는..

[Jetpack Compose] 왜 Jetpack Compose가 나와야만 했을까?

Jetpack Compose를 눈여겨 본지 1년정도 된 것같다. 오랫동안 xml로 레이아웃을 구성하면서 큰 불편함이 없어서인지, (불편함에 길들여졌었겠지) 이 새로운 기술이 정착될지, 도태될지 지켜보기만하고 실제로 시도해보지는 않았다. 원래는 Android Studio Preview에서만 지원되었으나 이제는 정식 지원하게 되었다. 내가 Jetpack Compose와 마주할때가 된 것 같다. Seperation of concerns xml을 사용하는 UI 디자인 방식에 무슨 문제가 있길래 Jetpack Compose가 등장했을까? 그것이 가장 궁금했다. SoC(관심사의 분리, Seperation of concerns) 원칙에 대해 들어봤을 것이다. 우리 프로그램은 하나의 거대한 시스템이고, 처리해야할 부분..