Ryan cooke android tools header

안드로이드의 일반적인 문제 해결을 위한 도구와 라이브러리 모음집

저는 Pinterest 핵심 경험 팀의 안드로이드 개발자인 Ryan Cooke입니다. 이번 강연에서는 여러 안드로이드의 라이브러리를 소개하고, 장단점과 사용 방법을 알려드립니다. 가능한 많은 라이브러리에 대해 심층적으로 다루면서 어떤 문제에 봉착했을 때 이 문제에 대한 해법이 있는지, 어떤 해법이 좋은지에 대해 알려드리고자 합니다. 또한, 쉽게 빠지기 쉬운 함정을 피하는 방법도 제시하고자 합니다.

적절한 라이브러리를 선택하면 솔루션 구축에 삼 개월을 소비하는 대신, 이미 구축된 더 나은 솔루션을 사용할 수 있습니다. 어떤 라이브러리들이 있는지 알아두는 것이 먼저겠죠?

많은 사람들이 첫 번째 라이브러리를 적용하면서 Async task를 사용할 지 네이티브한 것을 사용할지 고민합니다. 구글은 생태계에서 이미 솔루션이 구축된 경우 같은 동작을 하는 경쟁군을 만들지 않는 방침에 여러 번 언급했었죠. 하지만 어떤 옵션이 존재하는지 알아두는 것이 좋습니다.

일반적인 팁

라이브러리가 가지는 최고의 장점은 적용한 것을 취소할 수 있다는 점입니다. 라이브러리를 앱에 적용했다가 별다른 비용 없이 뺄 수 있으므로 적용과 배제가 언제든지 가능합니다. 모든 라이브러리가 그렇지는 않을 수 있지만, 적용을 취소할 수 있는 라이브러리를 사용한다면 한 번 적용했다고 앱에 평생 넣어둘 필요가 없으니 결정이 쉬워집니다.

라이브러리를 쉽게 빼는 방법은 라이브러리 래퍼를 작성하는 것입니다. 라이브러리 메서드를 호출하는 자체 클래스가 있는 경우 자신의 API를 가질 수 있으므로 많은 이점이 있습니다. 예를 들어 알 수 없는 값이 반환된 경우 API를 사용해서 이를 가져온다면 코드에서 하나의 파일만 수정하면 됩니다. 래퍼를 만들면 라이브러리 작업이 훨씬 쉬워지죠.

라이브러리를 작업하는 경우 팀원 중 이미 해당 라이브러리를 사용하며 사용법을 알고 있어서 여러분의 래퍼를 사용하지 않으려는 사람이 있으면 위의 체크 스타일 예제 코드와 같은 것을 사용하는 것이 도움이 됩니다. 이 체크 스타일은 빌드 타임에 오류를 던지거나 앱에서 연결 클래스를 가져오는 경우 연결 클래스를 사용하지 말고 래퍼를 사용하라고 알려줍니다. 래퍼 클래스에 대해 제대로 알려주지 않으면 다른 팀원들이 이를 깨뜨릴 수 있으므로 효용이 없어질 수 있기 때문입니다.

또한, 유닛 테스트 서드 파티 라이브러리를 사용하는 것이 좋습니다. Joda-Time 등을 적용한 경우 이상한 극한 케이스를 테스트하는 것에 유닛 테스트를 사용할 수 있습니다. 유닛 테스트를 통해 동작 방법을 잘 이해할 수 있고, 오늘 날짜에 하루를 더했는데 2월 30일이 나오는 것과 같은 이상 경우를 발견할 수 있습니다.

안드로이드에서는 메서드 카운트 (64,000)도 생각해야 합니다. method counts라는 사이트에서 라이브러리와 Gradle import 선언문을 넣으면 라이브러리에 얼마나 많은 메서드가 있는지 알려줍니다. ProGuard를 사용하면 여러 라이브러리가 많이 축소됩니다. 실제 사용되는 라이브러리 부분만 사용할 수 있게 됩니다. 실제로 사용하기 전에 어떤 것을 사용할지 예측하기는 어렵지만, 어떤 라이브러리에서 사용할 부분이 확실한 경우 그 부분의 크기가 얼마나 되는지 확인할 수 있겠죠.

Dex-method-counts는 사용자의 Gradle에 들어가며 여러분의 빌드 시스템에서 앱에 들어가는 전체 메서드 카운트를 추적할 수 있습니다. Apk-method-counts도 좋습니다. APK를 드래그해서 넣으면 얼마나 많은 메서드 카운트가 있는지 알려줍니다. 물론 MultiDex가 허용하는 메서드 카운트라도, 추가되는 모든 메서드는 예전 기기에서의 앱 시작 시간을 증가시킬 수 있습니다. MultiDex가 아니더라도 십만 개 메서드와 십이만 개의 메서드는 차이가 있을 수밖에 없죠. 항상 메서드를 적게 유지하는 편이 좋습니다. 인스타그램은 라이브러리를 통째로 사용하는 대신 라이브러리에서 필요한 부분만 빼내기로 유명합니다. 가용 인력이 있다면 이 방법도 좋을 겁니다.

그 외에도 인기 있고 어느 정도 성장한 라이브러리를 사용하는 것이 좋습니다. Reddit 등에서 매달 새롭고 멋진 라이브러리에 대한 소식이 들리지만, 더욱 오랜 기간 많이 개발되고 유명하며 주변의 사람들이 사용하는 것을 사용해야 호환성 이슈도 적고, 문제가 발생하면 Stack Overflow에서 해법을 쉽게 찾을 수 있습니다.

또한, 비정상적인 접근 방식, 즉 표준 Java 방식을 사용하지 않는 방식을 알고 있어야 합니다. 레이아웃을 완전히 다른 방식으로 만든다면, 호환성 문제를 예상해야 합니다. 라이브러리 사용을 주저하게 되는 이유죠.

소셜 로그인

페이스북은 소셜 로그인을 위한 좋은 표준입니다. 테스트 사용자를 제공하므로 가짜 계정을 만들지 않고 테스트 사용자 계정을 사용할 수 있습니다. 자주 하는 실수가 페이스북 가입 계정이라고 반드시 이메일이 있지는 않다는 점입니다. 약 10에서 15%의 페이스북 사용자가 이메일을 사용하지 않습니다. 이메일이 있다고 가정해서 이메일 인증을 진행하는 경우 10~15% 정도의 가입이 실패할 수 있습니다. 랜덤 키 해시를 사용되므로 이를 사용하면 됩니다. 다음 코드 조각을 사용하세요.

또한, 권한 관리가 강화됐으므로 이상한 방식의 권한을 사용한다면 주의하세요. 앱에서 실제로 사용하지 않는 권한들을 사용하면 어떻게 권한을 사용하는지 확인할 겁니다.

로그인과 가입에서 발생한 오류를 기록하세요. 저희는 로그를 통해 10~15%의 사용자가 이메일을 받지 못해 가입을 실패한 것을 발견했습니다. 에러를 로그로 기록하면 기존에 알지 못했던 것을 파악할 수 있습니다.

페이스북 말고도 트위터, 링크드인, 구글 등 많은 옵션이 있습니다. 사실 많은 경우 노력보다 결과가 좀 빈약한 경향이 있습니다. 아마 2% 미만이 트위터를 사용해서 로그인할 겁니다. 특히 링크드인은 API가 까다로우며, 트위터의 경우 정보가 적습니다. 물론 트위터에서 이메일과 기본 정보를 가져오고 싶은 경우 이 링크에서 권한을 모두에게 부여하긴 합니다. 하지만 결론적으로 꼭 필요한 경우가 아니라면 이런 로그인 옵션을 쓰는 것은 앱에 복잡성만 높일 뿐입니다.

구글은 중간쯤입니다. 안드로이드라면 많은 사람들이 구글 계정을 갖고 있습니다. 하지만 이메일 힌트나 여러 이메일 선택 등의 구현을 해야 하고 UI가 예쁘지 않은 데다 느리므로 대화창 로딩에 대해 고려해야 합니다.

네트워크

Retrofit, Volley 등이 네트워크 라이브러리로 유명합니다. 네이티브 HTML URL 커넥트도 있지만, 일반적으로는 추천하지 않습니다. Retrofit과 Volley의 경우 1:1 비교를 많이 찾을 수 있으며, Volley가 Retrofit보다 이미지 다운로드 등 여러 부분에서 많은 기능을 하지만 잘 살펴볼 필요가 있습니다.

이런 개발 뉴스를 더 만나보세요

Retrofit을 만든 Square는 라이브러리의 역할을 최소한으로 하는 철학을 가지고 있습니다. 즉, 라이브러리가 특정한 문제만을 풀도록 고안합니다. 또한, 문제를 해결하면서 사용자의 우수 사례를 만들려고 노력합니다. Retrofit이 가장 좋은 예인데, 위 코드는 제가 API를 호출하는데 매우 깔끔한 인터페이스를 만들어야 하는 랜덤 앱에서 Retrofit을 사용한 예제입니다.

Volley는 쉽게 사용할 수 있지만 잘못 사용하기 쉽습니다. Retrofit는 우수 사례를 강제해서 더 나은 코드를 만들게 하므로 저는 Retrofit을 선호합니다.

OkHttp도 많이 들어봤을 겁니다. 실제로 네트워크 호출을 하면 코드 뒤에서 실제로 동작하는 부분으로, 안드로이드 4.4에 네이티브로 들어가 있습니다.

네트워크 디버깅

네트워크 코드를 디버깅하는 경우 네트워크가 어떤 식으로 이뤄지는지 이해해야 합니다.

Stetho

크롬 개발자 도구 뷰에서 네트워크 호출을 볼 수 있는 페이스북의 Stetho를 추천합니다. 그밖에도 여러 좋은 기능을 제공합니다. 데이터베이스 내부를 보면서 동작 내용을 확인하거나, 레이아웃을 볼 수도 있습니다. 화면에서 벌어지는 일을 파악할 수도 있습니다. 주의할 점은 각 단계 실행 시마다 동작시키지 않으면 저절로 닫혀버린다는 점입니다. 또한, 사용할 때 네트워크 호출에 더 많은 시간이 걸릴 수 있습니다.

HttpLoggingInterceptor

저는 간단한 HttpLoggingInterceptor를 좋아합니다. 인터셉터를 네트워크 요청에 추가하면 동작 내용을 로그 파일에 출력해줍니다. 또한, JSON 파일도 볼 수 있습니다. 로깅 인터셉터(logging interceptor)라는 이름으로 유사한 것들이 많은데, Square의 표준 HTTP 로깅은 가볍고 쉽게 볼 수 있어 좋습니다.

이미지

저는 Pinterest의 개발자이므로 이미지 처리가 중요합니다. 이미지 처리에 캐시, 다운로드, 리사이징 등을 위해 서드 파티 라이브러리를 사용하는 분이 많을 겁니다.

Picasso, Glide

이미지 처리에는 Picasso와 Glide를 빼놓을 수 없겠죠. 유사한 인터페이스를 가지며 대부분의 유스 케이스에 같은 코드를 제공합니다.

최신 버전의 경우 Picasso는 849줄, Glide는 2,879줄로 둘 중에 Picasso가 더 작습니다. 단, Glide를 사용하면 거의 모든 유스 케이스를 지원해 줍니다. GIF를 가져오거나 비디오 프리뷰도 가능합니다.

Picasso는 이미지 로딩이라는 특정 사용에 초점을 맞췄습니다. 좀 더 많은 사람이 사용하고 문서도 많으며 지원 범위도 넓습니다. 두 라이브러리 모두 좋은 라이브러리이므로, 좀 특이한 유스 케이스인 경우 Glide를, 표준적인 유스 케이스라면 Picasso를 사용하시는 것을 권장합니다.

앞서 말했듯 저는 Pinterest에서 일하므로 이미지가 정말 중요합니다. 이미지에 대한 팁을 좀 더 공유해드리겠습니다.

많은 사람들이 위 라이브러리들이 지원하지 않으므로 목록에서 미리 가져오기를 하지 않습니다. 따라서 리스트를 스크롤 하는 경우 모든 이미지가 그 자리에서 로딩되곤 합니다. 만약 다음 이미지를 하나나 두 개 정도 미리 가져온다면 스크롤 시의 프레임율 저하를 개선할 수 있습니다. 스크롤할 때의 기다림이 줄어들면 사용자의 참여도 늘어날 수 있을 겁니다. 하지만 너무 많은 이미지를 미리 가져온다면 리소스 낭비도 일어날 수 있습니다. 따라서 사용자 경험 개선을 위해서는 한두 개의 다음 이미지를 미리 가져오는 것을 추천합니다.

단, 이 방법으로는 이미지 메모리 문제를 해결할 수 없습니다. 가장 쉬운 해결책은 이미지를 사용 중지하는 것으로, 이미지를 프로파일링하지 못하게 설정한 다음 앱의 메모리를 이미지가 얼마나 소비하는지 확인하는 것입니다. 가장 간단하게는 이미지를 깬 다음 메모리가 얼마나 절약됐는지 확인할 수 있습니다. 아니면 표시하는 것보다 큰 크기를 가진 이미지를 리사이즈하는 방법도 있습니다. Cloudinary라는 호스팅 서비스를 사용하면 이미지를 특정 해상도로 요청할 수 있습니다. 하지만 너무 자주 리사이징을 요청한다면 유사한 이미지를 요청해서 캐시를 무용지물로 망가뜨리지 않도록 조심해야 합니다. 둘 사이의 상충 관계를 고려해야 하죠.

저는 largeHeap을 좋아합니다. 앱에서 largeHeap을 활성화하면 메모리 부족(OOM) 크래시가 1/4 정도 감소했습니다. 이 옵션을 사용하면 백그라운드의 다른 앱이 종료되기 때문에 구글은 권장하지 않으므로, 앱을 전환하는 것은 좋지 않습니다. 하지만 사실 앱 개발자의 문제는 아니죠. GC 시간이 오래 걸리게 되므로 메모리 문제를 마스킹하는데 사용할 수도 있지만, 권장하는 방법은 아닙니다. 일반적으로는 largeHeap이 유용합니다. 플레이 스토어에서 largeHeap으로 검색하면 이 옵션을 켜둔 앱을 모두 찾아주는 앱도 있습니다. 거의 모든 앱이 largeHeap을 사용하고 있습니다.

메모리와 이미지 사이에는 간단한 공식이 있습니다. 어떤 사람들은 “이 JPEG는 2kb인데 왜 실제 메모리에서는 이렇게 크죠?”라고 생각하는 사람도 있겠지만, 메모리는 픽셀의 가로 곱하기 픽셀의 세로에 다시 4를 곱한 크기(픽셀 가로 x 픽셀 세로 x 4)가 됩니다. 표준 포맷은 ARGB_8888인데, 컬러값 저장을 위해 4바이트를 사용하기 때문이죠. RGB_565를 사용하면 절반으로 줄일 수 있습니다. 알파 값을 설정할 수 없긴 하지만 메모리 사용량을 줄일 수 있습니다. 램 용량이 적인 기기나 낮은 API를 고려한다면 OOM 문제를 해결하기 위해 도입할 만합니다.

Fresco

페이스북은 21 이하의 API에서 발생하던 거의 모든 OOM 이슈를 해결하는 훌륭한 라이브러리를 출시했습니다. API 21 이하의 안드로이드 시스템에는 앱의 메모리 밖에서 메모리를 사용할 수 있는 버그가 있었습니다. 이를 이용해서 오래된 장치에서 메모리 부족을 겪지 않도록 했지만 새로운 기기에 사용하면 성능을 저하합니다. 다른 라이브러리와는 다른 방식으로 로딩하므로 프로그레시브 JPEG와 같은 방식으로 이미지를 레이어에 올릴 수 있습니다. Glide와 Picasso를 사용하면 코드를 다른 수준으로 사용해야 합니다. imageViews를 사용하는 대신 Drawee 타입을 사용할 수 있고 더 독립적인 코드를 유지할 수 있습니다.

낮은 기기를 타깃으로 하는 경우 OOM을 방지해주는 Fresco를 추천합니다. 그렇지 않은 경우라면 Picasso나 Glide가 좋습니다.

메모리 누수

LeakCanary

LeakCanary는 메모리 누수를 파악하는 데 도움을 주는 도구입니다. 누수 외에도 다른 메모리 문제들이 있지만, 가장 중요한 것은 역시 누수가죠. 앱에 LeakCanary를 추가하면 자동으로 액티비티의 메모리 누수를 감시하기 시작합니다. LeakCanary를 적용한 사람들이 단지 한 두 개의 누수를 고치고는 더 이상 메모리 누수가 없다고 생각하기 쉽지만 LeakCanary는 단지 액티비티만 감지하므로 주의해야 합니다. 위 그림과 같은 코드를 사용하면 프래그먼트를 감시하도록 할 수 있습니다. 하지만 이 코드를 적용해도 모든 누수를 잡을 수 있는 것은 아닙니다. 액티비티와 프래그먼트를 감시하는 것이 좋긴 하지만 객체 역시 감시해야 합니다.

LeakCanary는 훌륭한 동작 방식을 보여 줍니다. 참조하는 객체에 대한 약한 참조로서 더 이상 참조되지 않을 것으로 예상되는 객체에 코드의 파괴 지점에 연결합니다. 그러면 가비지 컬렉션을 해주는데, 객체가 아직 존재하는 경우라면 메모리 누수임을 감지하고, 어떤 것이 계속 참조하고 있는지 확인합니다. 홈 프래그먼트와 진행되는 이 참조를 제공하는데 개발자마다 호불호가 갈리는 표시 방법이긴 합니다.

위 그림 예제를 간단히 설명하면 하단의 홈 프래그먼트부터 시작합니다. 다시 한 단계 위로 핀 그리드 프래그먼트로 참조해 들어갑니다. 핀 그리드 프래그먼트는 해당 객체의 부모이죠. 다음으로 이상한 $0이라는 것이 보이는데 이는 러너블을 표시합니다. 객체 내의 핸들러가 러너블을 가지는 것입니다. 핸들러가 더 이상 러너블을 붙잡고 있지 않도록 해야겠죠. 이 경우 뷰의 파괴 부분에서 모든 러너블과 핸들러를 지우면 메모리 누수를 고칠 수 있을 겁니다.

WeakHandler

WeakHandler를 사용하면 핸들러 참조를 약한 참조로 만들 수 있습니다. 이 경우 가비지 컬렉션이 가능해집니다. 단점은 가비지 컬렉션을 예상하지 못한 것이 가비지 컬렉팅될 수 있다는 점입니다. 대부분의 메모리 누수는 일반적으로 누락되지 않은 클래스가 외부 클래스를 잡고 있는 동안 진행된다는 점을 이해해야 합니다. 누수를 잡으려면 이 부분을 집중해서 파악하는 것이 좋습니다. 또한, 메모리 누수에 대한 버그 분류 접근법을 사용하는 것도 좋습니다. 휴대폰에서 70개의 메모리 누수가 발생한다면 최악일 테죠. 팀의 일원으로 우리가 메모리 누수를 발견하면 어떻게 할지 항상 생각해보는 것이 좋습니다.

UI

최근 한창 논쟁이 뜨거운 부분입니다. 이전 표준인 액티비티가 있었고, 재사용성을 위해 프래그먼트가 등장했지만, 프래그먼트는 위 그림처럼 정말 복잡하죠. 뷰 기반 아키텍처(View-Based-Architecture)라는 다른 접근법이 인기를 얻고 있습니다. 뷰 기반 아키텍처에서는 프레임 레이아웃을 사용하고, 네이티브 안드로이드 내비게이션을 사용하는 대신 프레임 레이아웃 내부의 모든 것을 바꿀 수 있습니다. 이 방식으로 프래그먼트의 복잡성을 해결할 수 있습니다.

프래그먼트는 점차 단순해져서 최신 버전의 경우 많이 안정화됐지만 뷰 기반 아키텍처에 대한 논쟁은 아직 뜨겁습니다. 더 자세한 내용은 위 그림의 하단에 소개한 라이브러리를 살펴보세요.

뷰 기반 아키텍처(View-Based-Architecture)

시작은 Mortar와 Flow였습니다. 제 생각으로는 이들이 뷰 기반 아키텍처를 대중화한 최초의 제품입니다. Flow는 뷰 기반 아키텍처를 수행하는 실제 제품이며, Mortar가 모델 뷰 프리젠터 타입의 접근을 시작했습니다. 뷰 기반 아키텍처를 적용하는 경우 이상한 솔루션을 적용하지 않도록 조심하세요.

뷰 기반으로 앱을 만드는 경우 여러 이슈에 부딪힐 수 있습니다. 액티비티의 경우 잘 동작하지만 뷰에서는 문제를 해결해야 하죠. 뷰 기반으로 만드는 경우 액티비티 결과나 권한, 백 버튼과 내비게이션 파악 등 여러 가지 표준 이슈가 있습니다.

Mortar과 Flow는 기본 내비게이션 단계를 수행하지만, 화면 상태 저장 등 여러 이슈를 해결해주지는 않습니다.

Conductor에는 모든 뷰 기반 아키텍처가 가지는 문제가 고스란히 있으며, 상태 저장, 전환 등의 솔루션을 만들긴 했지만, 여전히 호환성 문제가 남아 있습니다.

Lyft의 Scoop은 직접 실제 제품에 사용하고 있습니다. 뷰 기반 아키텍처 접근법에서 가장 프로덕션 레벨로 테스트를 마친 제품입니다. 상태를 저장하지 않기 때문에 Lyft 역시 상태를 저장하지 않습니다. 가장 아쉬운 점은 전환을 쉽게 사용할 수 있지만, 제한적이라는 점입니다.

정리하자면 상태를 저장할 필요가 없는 경우에는 Scoop이 가장 프로덕션 레벨로 사용하기 안전할 겁니다. Conductor도 좋습니다.

모델 뷰 프리젠터 (MVP)

코드를 뷰 로직, 코어 안드로이드에서 분리해주는 모델 뷰 프리젠터 구조를 위한 좋은 라이브러리가 몇 가지 있습니다. 프리젠터가 분리되면 유닛 테스트도 가능해집니다. 이론적으로는 진행 중인 비즈니스 로직을 다시 작업하지 않고도 뷰를 변경할 수 있습니다.

MVP를 위한 첫 번째 추천은 Mosby입니다. Mosby를 적용하지 않더라도 안드로이드에 특화된 컨텍스트 튜토리얼을 제공하고 있으니 확인해 보세요. 핵심 기능은 프리젠터를 위한 뷰 상태를 제공하는 것입니다.

Nucleus도 비슷합니다. Mortar와 Flow도 초기에 사용됐지만, 가치 이상으로 많은 문제점이 있습니다. 종종 기업들은 직접 MVP를 구축하곤 합니다. OnCreate에서 프리젠터를 시작하고 OnDestroy에서 프리젠터를 멈춥니다. 각 액티비티 등 뷰가 기반으로 하는 것은 해당하는 프리젠터를 보유하게 됩니다.

하나의 유스 케이스를 보면 MVP로 생각할 수 있는 많은 경우가 있습니다. 어디에 무엇이 살아 있는지 알고 이를 강제할 방법을 찾아내는 것이 MVP의 가장 어려운 부분입니다. 하지만 MVP를 사용하면 유닛 테스트가 가능한 코드를 만들 수 있으므로 더욱 안정적인 코드가 된다는 장점이 있습니다.

성능 테스트

NimbleDroid

테스트를 위한 여러 도구가 있지만, 간단히 정리하자면 유닛 테스트에는 JUnit 4가 있고, Gradle의 빌드 시스템이나 Espresso도 있어서 이들을 사용하는 것이 일반적입니다. 한편 아직 성능 테스트 도구 부분에는 표준이 형성되지 않았습니다.

성능 테스트에는 두 가지 접근이 있습니다. 구글은 프레임율 저하에 Systrace 타입의 접근 방식을 사용합니다. 이 경우 거의 작동하는 코드를 제공하는 코드 랩이 있어서 자동화 성능 테스트로 프레임율 저하가 악화되는지 확인할 수 있습니다.

NimbleDroid는 APK를 업로드할 수 있는 무료 평가판 옵션이 있어서, 앱의 시작 시간을 포함한 여러 핵심 흐름을 자동으로 테스트해줍니다. 메서드 분해와 시간 측정도 해줍니다. 회귀 테스트 도구로 사용하려면 비용이 많이 들긴 하지만 시작 시간이 지연되거나 핵심 흐름이 느려진 경우를 파악하도록 도와줍니다. 성능이 매우 중요하다면 고려할 만합니다.

JSON

많은 사람들이 성능 측정을 위해 JSON을 고려합니다. 많은 JSON 라이브러리가 있지만, 성능만을 위해 도입하는 것은 주의해야 합니다. 150kb 크기로 3만 줄의 거대한 JSON 요청을 GSON과 Jackson으로 돌려 봤더니 약 20 밀리 초가 걸렸습니다. 크기에 비하면 준수한 속도이죠.

사용하기 쉽고 문서화가 잘 된 라이브러리를 사용하는 것을 추천합니다. 지원이 잘 되는 것도 중요합니다. Stack Overflow에서 해결책을 찾을 수 없어서 개발 시간을 몇 주간이나 허비하고 싶진 않겠죠. 성능이 가장 높은 라이브러리는 아니지만, 이런 점에서 GSON과 Jackson은 가장 크고 유명한 라이브러리입니다. 특히 안드로이드라면 GSON이 좋습니다.

Square의 Moshi도 있는데 GSON과 아주 유사합니다. GSON을 어떻게 사용해야 하는지 방향성을 제시하고 있는데 의견이 갈리기도 하지만 대체로 아주 틀린 방향은 아닌 것 같습니다.

빠른 JSON 파싱 성능을 고려한다면 LoganSquare도 좋습니다. 다른 라이브러리는 컴파일 타임에 수행하는 많은 일을 런타임에 해줍니다. 덕분에 시간의 1/4, 혹은 4배의 성능 개선을 얻을 수 있습니다. 하지만 정말 JSON 성능이 중요하다면 JSON을 사용해서는 안 됩니다.

대신 Flatbuffer를 사용하세요. JSON은 사람이 읽을 수 있는 형태이지만 Flatbuffer는 읽을 수 없는 형태이며, 이 이유로 많은 필요 없는 부분을 줄일 수 있습니다. 또한, JSON과 비교하면 파싱은 거의 순식간에 해결합니다. 페이스북은 이를 도입해서 시작 시간을 10~15% 정도 빠르게 했습니다. 메모리 사용량도 개선했죠. 단, JSON보다 다루기가 어려우므로 주의가 필요합니다.

데이터베이스 - SQL

데이터베이스로는 표준 안드로이드 라이브러리인 일반적인 SQLite를 이미 알고 계시겠죠?

SQLite 위에 쉽게 얹을 수 있는 것은 SQLBrite입니다. 데이터베이스에 리액티브 인터페이스를 제공합니다. 사용자가 뭔가 변경하면 알림을 받고 UI를 업데이트할 수 있습니다. 작은 라이브러리이지만 SQL 작업에 편리합니다.

Square의 SQLDelight도 있습니다. SQLDelight는 완전한 ORM이 되기 보다는 ORM 코드의 단점을 개선하고 안전한 타입을 제공하고 SQL 문을 체계적으로 구성할 수 있게 해서 데이터베이스를 쉽게 작업할 수 있게 합니다.

완전한 ORM을 원한다면 GreenDAO, OrmLite, DBFlow 등도 있습니다. 각기 자신들이 최고의 성능을 가졌다고 자랑하면서 다른 라이브러리보다 100배 빠르다는 그래프를 제시합니다. 이 중 쉽게 사용할 수 있는 것을 1순위로, 성능을 2순위로 두고 찾아보는 것을 추천합니다.

데이터베이스 - NoSQL

Realm은 NoSQL로 정말 빠릅니다. 또한, 다른 데이터베이스 라이브러리들과는 달리 문서가 잘 만들어져 있고 지원도 잘해줍니다. 이런 장점으로 Realm을 사용하면 데이터베이스 타입에 관계없이 전체 개발 시간을 크게 단축할 수 있습니다.

구글의 NoSQL인 LevelDB도 있습니다. 키-값 쌍이지만 각 단계를 직접 파악해야 하는 단점이 있는데, Realm은 이런 단점이 없습니다.

제가 생각하는 Realm 데이터베이스의 단점은 용량입니다. Realm은 네이티브 라이브러리이므로 칩 아키텍처마다 앱에 Realm 데이터베이스의 전체 복사본을 포함하게 됩니다. 이를 방지하려면 Gradle에 위 코드를 사용해서 아키텍처마다 별도의 APK를 만드세요. 이렇게 하면 메모리 크기를 많이 줄일 수 있습니다. 이 방식이 네이티브로 실행되는 C++ 코드에는 다 적용되므로 Crashlytics 등 유명한 라이브러리를 사용할 때 이득이 됩니다.

구글 플레이 스토어 앱인 Native Lib도 있습니다. 휴대폰에 있는 앱들이 어떤 라이브러리를 사용했는지와 자신의 폰이 아닌 코드를 위한 APK 라이브러리를 다운받을 수 있는지 표시해 줍니다.

다시 위 코드로 돌아가자면, 위 코드를 사용하면 메모리 사이즈가 줄어듭니다. 휴대폰에 데이터를 저장하려면 실제 기기에 저장해야 하므로 인스턴트 앱에는 사용하지 마세요. 너무 작은 용량을 가진 기기에는 저장할 수 없겠지만, 결론적으로 Realm은 아주 훌륭한 데이터베이스 솔루션입니다.

데이터베이스 - 모바일 플랫폼

모바일 플랫폼도 있습니다. 서버 가이드가 더 이상 필요없는 모바일 개발자의 이상향이죠. 앱을 직접 빌드할 수 있는 기존 서비스로는 이제는 종료된 Parse가 가장 이상적이었습니다.

이제 모바일 플랫폼의 강자는 Firebase와 Realm입니다. 둘 다 NoSQL 모델이므로 쿼리에 적응할 필요가 있긴 하지만 정말 빠릅니다. 동기적 업데이트에도 안성맞춤입니다. 채팅이 가장 좋은 예로, 메시지를 보내면 모든 기기가 업데이트되는 앱을 만들기 위해 데이터베이스를 직접 구축하고 서버 개발자와 협업하는 대신 위 솔루션들을 사용할 수 있습니다. 빠르게 앱을 개발하고 서비스할 수 있다는 장점이 있습니다.

Realm이 가진 Firebase와의 차별점은 오프라인 우선 기능에 초점을 맞추고 있다는 점입니다. 둘 다 오프라인 기능이 되지만 Firebase의 경우 우선순위가 낮습니다. 온라인 동작이 필요없는 앱이 많이 있고, 오프라인에서 모든 기능이 기본적으로 완벽하게 동작하게 한 이후에 온라인 작업을 정상적으로 수행할 수 있도록 하는 것이 좋으므로 Realm은 그 부분에 초점을 맞췄습니다.

애널리틱스

무언가를 측정할 수 있으면 최적화도 할 수 있습니다. 정확한 숫자를 알지 못한다면 개선하기 어렵죠. 특정 기능을 사용하는 사람이 있는지, 개선할 수 있는지 알려면 자세한 애널리틱스가 필요합니다.

애널리틱스를 위해 서드 파티 라이브러리를 래핑해서 사용할 수 있습니다. 애널리틱스 라이브러리를 래핑하면 실제 코드를 건드리지 않고도 자신의 애널리틱스 도구를 교체할 수 있습니다. 새 애널리틱스 서비스를 추가해서 이전 것과 동시에 사용할 수 있어야 합니다. 따라서 애널리틱스 코드에 래퍼를 사용하는 것이 좋습니다.

애널리틱스를 쉽게 추가하는 방법은 화면을 로그로 기록하는 것입니다. 사람들이 어떤 화면으로 이동하는지 로그를 남기고 추상(abstract) 액티비티에 넣으면 많은 값을 빠르게 확인할 수 있습니다.

종종 너무 많은 애널리틱스를 추가해서 혼란스러워지는 실수를 하게 됩니다. 모든 곳에 몇천 개의 이벤트를 넣는다면 이 애널리틱스 내용이 어떤 뜻인지 파악할 수 없을 겁니다. 따라서 애널리틱스를 추가할 때는 매우 신중해야 합니다. 쉬운 결정을 지연시키는 애널리틱스를 사용하기보다는 그냥 쉬운 결정을 따르세요. 혹시 사람들이 공짜를 싫어한다는 애널리틱스 결과가 나온다면 틀렸다고 가정하세요. 간혹 애널리틱스로 잘못된 결론이 도출될 수도 있습니다. 중요한 의사 결정을 하는 경우에는 애널리틱스가 잘못되지는 않은지 다시 확인하는 편이 좋습니다.

Firebase

원래 Firebase는 실시간 데이터베이스였지만, 구글이 여러 개의 도구를 묶어 Firebase로 부르기 시작하면서 혼란이 있습니다. Firebase 애널리틱스는 모든 Firebase 도구의 기초가 됩니다. 구글은 iOS와 안드로이드 개발자들이 같은 문제를 해결하기 위해 서드 파티 서비스를 유료로 사용하고 있다는 것에 주목하고, 앱을 쉽게 만들 수 있도록 했습니다. 많은 경쟁 제품들이 있었지만, 애널리틱스 도구를 근간으로 제공하면서 모든 도구를 강화하도록 노력했습니다. 크래시 리포트와 애널리틱스를 제공하면서, 크래시를 소모 비용에 따라 정렬해주기도 합니다. 이 방식으로 가장 비용이 높은 크래시에 대한 알림을 받고 사람들에게 무료 크래딧을 제공할 수도 있습니다.

이런 것을 하나로 묶는다는 것은 멋진 비전입니다. 사실 아직은 그런 비전이 현실화되진 않았고, 몇몇 기능은 아직 개발 중입니다. 아직 경쟁 제품보다 좋지 않은 수준의 도구들도 있습니다. 하지만 무료 애널리틱스가 매력적이고, 이벤트도 무제한이므로 한 번 시도해보는 것도 좋을 겁니다.

구글 애널리틱스도 유명합니다. 사용자의 기본 정보를 쉽게 알 수 있습니다. 사용자가 이벤트 사이를 옮겨 다니는 것을 볼 수 있도록 사용자의 행동 흐름을 그래프로 보여주는 것도 유용합니다. 단, 이벤트 로그 스타일 등을 보면 조금 오래된 감이 있습니다. 역시 무료이며, 이 대체로 Firebase가 등장했습니다.

A/B 테스트

개인적으로는 A/B 테스트가 과장되는 면이 있다고 생각합니다. 사용자에게 각기 다른 기능을 제공해서 사용자들이 어떤 기능을 어떤 비율로 선호하는지 알 수 있습니다.

하지만 버그를 만드는 것에도 일조합니다. 기본적으로 A/B 테스트로 인해 앱의 버전이 2의 테스트 숫자 승으로 증가하죠. 3개의 A/B 테스트가 있다면 8개의 앱 버전이 함께 동작해야 합니다.

저는 사용자 분석 서비스를 사용하는 것을 추천합니다. 특히 Mixpanel은 멋진 A/B 테스트 도구와 애널리틱스 기능을 갖추고 있습니다. A/B 테스트를 위한 도구도 많이 개발됐는데, 가장 유명한 것은 Optimizely와 Apptomize이며, 이 중 Optimizely는 좀 더 웹을 대상으로 하고 있습니다. 둘 다 여러 개의 버전 제공을 돕고 어떤 것이 유효한 통계를 내는지 알 수 있게 합니다.

Firebase Remote Config는 A/B 테스트용으로 개발하진 않았지만, 기술적으로 A/B 테스트를 할 수 있습니다. 이 서비스로 업데이트없이도 키-값을 서버에서 보낼 수 있기 때문입니다. 두 개의 다른 버전에 다른 키-값 쌍을 보내고 이 쌍에 따라 코드에서 할 일을 결정하면 됩니다. 그런 다음 애널리틱스에 전달하고 분석합니다.

스토어 목록에서 A/B 테스트를 할 수 있습니다. 여러 국가에 서비스한다면 쉽게 할 수 있고 몇 가지 이점이 있으므로 시도할 만합니다.

크래시 리포트

애널리틱스처럼 크래시 리포트를 위한 솔루션이 많습니다. 이 중 몇 개만 소개하겠습니다.

안드로이드를 처음 접하는 사람은 플레이 스토어를 먼저 보게 됩니다. 크래시가 발생하면 리포트를 하는 옵션 창이 뜨지만, 많은 사람들이 이를 무시하므로 크래시의 약 1%만이 수집됩니다. 하지만 큰 숫자의 알 수 없는 크래시가 빈번히 발생한다면 어떤 일이 발생했는지 사용자가 의견을 말해주는 경우도 있으므로 확인할 필요가 있습니다. 사실 의견의 대부분이 크래시가 났다, 짜증 난다 정도일 수 있지만 가끔은 이 화면에서 폰을 세로로 돌렸더니 크래시가 났다는 식으로 자세한 리포트가 오는 경우도 있습니다.

Crashlytics는 점점 인기가 높아지고 있습니다. Twitter의 Fabric 일부로 제공됐었는데 이제는 Google의 Fabric이 됐습니다. 매우 양질의 조직적인 크래시 보고를 무료로 볼 수 있습니다. 단, 정렬이나 우선순위를 정하는 것을 직접 해야 하며, 검색과 쿼리가 좀 어렵다는 단점이 있습니다. Bugsnag을 추가로 사용해서 좀 더 나은 검색과 쿼리를 사용하는 사람도 있습니다. 하지만 Bugsnag는 유료입니다.

Instabug와 Telescope도 소개하겠습니다. Telescope는 크래시 보다는 폰을 사용하면서 뭔가 잘못되는 것을 리포트하는 데 집중합니다. 팀의 디자이너가 잘못된 것을 파악하는 경우 유용합니다. 물론 JIRA 티켓을 제출하거나 다른 사람이 이미 이를 고치고 있는지 파악하는 것 같이 고차원의 일을 해주지는 않지만, 알파/베타 사용자나 회사 내의 다른 사람들이 이 도구를 사용해서 뭔가 잘못된 부분을 알려줄 수 있습니다.

푸시 알림

개발자라면 푸시 알림으로 GCM이나 GCM에서 이름이 바뀐 Firebase Cloud Messaging을 사용하고 싶을 겁니다. 하지만 이 도구는 마케팅 팀원가 사용하기 어렵다는 단점이 있습니다. 이미 좋은 애널리틱스 서비스를 사용하고 있는 경우 쉬운 방법은 Firebase와 Mixpanel 등으로, 이들 역시 알림을 발송해줍니다. 이벤트 기반으로 알림을 발송할 수 있죠. 한 번도 구매를 안했지만 세 번 검색해본 사용자에게 구매를 제안할 수도 있습니다.

좀 더 정교한 일을 하고 싶다면 푸시 알림에 집중하는 Urban Airship도 있습니다. Urban Airship은 사람들이 푸시 메시지를 첫 60자만 볼 것이라고 알려주면서 “믿지 못하시겠지만…“처럼 메시지를 잘라 버립니다. 사람들이 이 메시지를 눌러서 다음 화면으로 넘어간 이후에는 원래 푸시 메시지가 무엇이었는지 기억하지 못하죠. Urban Airship은 이런 식의 사려 깊은 푸시 알림 서비스를 만들도록 도와줍니다.

Kahuna는 최근 인기가 높아지고 있지만, 개인적으로는 추천하지 않습니다. 내세우는 바는 멋지긴 한데, AI를 사용해서 특정인에게 알림을 언제 보내면 좋은지 등을 파악하고 텍스트 메시지나 푸시 알림을 보낼 수 있도록 한다고 합니다. 하지만 아직 그 정도까지는 아니고 텍스트를 좀 변화시켜서 푸시 메시지의 실행률을 높이는 정도입니다. 아이디어는 멋지고 선전하는 모든 기능이 제공되면 좋겠지만, 아직은 시작 수준이며 알림이 다른 사용자에게 가는 등의 이슈도 많습니다. 사용자들이 뒤섞여서 같은 사용자로 취급되기도 했습니다. 좋은 경험을 했다는 사람도 있지만, 개인적으로는 이 서비스로 좌절한 경험이 있습니다.

개발을 쉽게 만드는 도구

개발을 쉽게 도와주는 훌륭한 도구들이 많이 있습니다.

가장 먼저 소개할 도구는 Butter Knife (@indVView)로 코드를 더 깔끔하게 만들 수 있습니다. 모든 뷰를 찾을 필요 없이 @BindView 를 쓸 수 있습니다. 안드로이드 스튜디오 플러그인인 Zelezny를 사용하면, 레이아웃으로 이동할 때 자동으로 BindView와 OnClick을 만들어 줘서 타이핑 시간을 줄일 수 있습니다. 다만 Butter Knife와 같은 어노테이션 도구를 사용하면 빌드가 좀 느려질 수 있습니다. 저는 어노테이션 프로세싱 도구를 좋아하지만 이런 단점을 인정하지 않을 수 없습니다. JRebel은 특정 라이브러리에 대한 빌드를 위해 이를 수정했다고 하는군요. 아무튼 결론적으로 Butter Knife는 훌륭한 라이브러리입니다.

Jake Wharton이 만든 라이브러리, Hugo도 있습니다. 메서드 상단에 @Debug.Log 를 넣으면 메서드 수행에 걸리는 시간과 들어온 매개 변수를 출력해 줍니다. 특히 현장에서 성능을 로그로 남기는 데 유용합니다. 어떤 변수를 캐시로 남겨야 할지, 특정 메서드가 호출되는 데 너무 오랜 시간이 걸리는지와 같은 것을 실제 시간으로 파악할 수 있게 해서 백그라운드 스레드에 넣을지, 그대로 놔둘지 등을 결정할 수 있도록 도와줍니다. 실제로 몇 밀리 초가 걸리는지 쉬운 코드로 알 수 있으므로 유용하죠.

Dart & Henson은 키-값 쌍 대신 어떤 값인지 인텐트에서 알 수 있습니다. 간단한 어노테이션 매핑으로 인텐트 사이에서 특정 값을 알 수 있게 해줍니다. 다른 접근 방식은 호출한 액티비티의 스태틱 인텐트를 사용하는 것으로, 필요한 것을 매개 변수로 넘길 수 있습니다. 에러를 방지하는 데 도움이 됩니다.

람다를 좋아한다면 Retrolambda를 사용해 보세요. 단점은 일반 익명 클래스에 네 개의 메서드를 생성한다는 것입니다. 또한, 코드의 가독성도 조금 떨어집니다. 하지만 결정은 여러분의 몫입니다.

처음 도입할 때는 개발이 어려워질 수 있는 도구

이제 처음 적용하기 시작하는 시점에서는 개발을 더욱 어렵게 만드는 것처럼 보이는 도구에 대해 말씀드리겠습니다. 결론적으로는 이들 역시 모두 훌륭한 도구입니다.

RxJava

일반 코드에서는 A 지점에서 시작하면 B 지점에 도달하게 되지만, 안드로이드라면 A에서 시작하더라도 사용자가 다른 것을 누르면 그것을 해줘야 합니다. 또한, 알림이 들어와도 다른 작업을 처리해야 하죠. 데이터베이스 요청이 오면 여기에도 반응해줘야 합니다. 리액티브란 앱에 들어온 신호에 반응해서 올바르게 처리하도록 하는 방식입니다.

학습 곡선이 있으므로 처음 시작할 때는 어렵게 느껴질 수 있습니다. 게다가 코드를 지나치게 줄인다면 처음 RxJava를 시작하는 사람이 읽기 어렵죠. 네트워크 코드가 가장 쉽습니다. 표준 케이스가 있는 경우 이를 사용할 수 있으며, 베스트 프랙티스인지 확인하세요. 모든 부분에 적용할 수 있다면 강력한 효과를 발휘하지만, 새 개발자가 들어온 경우 각 화면에서 무슨 일이 일어나는 것인지 모두 설명해줘야 한다는 단점이 있습니다.

또한, 잘못 사용하기도 쉽습니다. 몇몇 RxJava 관련 강연에서도 제대로 사용하고 있지 않은 경우가 있습니다. 예를 들어 네트워크 호출을 구독 취소하지 않는다면, 화면이 존재하지 않는데도 콜백을 받고 크래시가 날 수 있습니다. 주의해서 사용해야 하지만 전반적으로 훌륭한 도구입니다.

Kotlin

Kotlin을 사용하면 훨씬 깔끔한 코드를 생성할 수 있습니다. 가독성도 높고 의도도 명확합니다.

가장 큰 단점은 랜덤으로 실패하는 경우가 있으므로, 실패한 경우 Kotlin을 의심하게 된다는 것입니다. Kotlin의 잘못일 수도 있고 아닐 수도 있지만, 이를 파악하는데 많은 시간을 허비할 수도 있죠. 예를 들어 Gradle 빌드 업데이트가 잘 안 되는 경우 Kotlin의 문제일 수도 있고 아닐 수도 있지만 일단 Kotlin부터 살펴보게 됩니다.

마찬가지로 안드로이드 스튜디오도 가끔 크래시가 납니다. ProGuard가 어떤 Kotlin 클래스를 지워버려서 동작하지 않을 수도 있습니다. 이런 일이 꽤 자주 발생하고 원복하기도 어렵습니다. Kotlin에는 많은 상충효과가 있으므로 이를 고려해야 합니다. 코드에 넣어서 몇 가지 이슈가 발생할 수도 있지만, 빠르게 코드 리뷰를 할 수 있기도 합니다. 한편, 처음 배우는 사람에게는 학습 곡선도 있습니다. 여기에서도 결정은 여러분의 몫입니다.

카메라

안드로이드에서 카메라 작업을 네이티브로 해본 적이 있다면 어렵지 않았을 겁니다. 카메라 one API와 two API가 있는데, two가 one보다 낫지 않고 아주 최신 기종만 사용할 것이 아니라면 one을 사용하는 편이 좋습니다. 카메라를 사용하려면 카메라 인텐트를 쓰는 것을 추천합니다. 카메라가 핵심 기능이 아니라면 다른 사람들의 라이브러리를 써도 좋습니다.

Material Camera라는 라이브러리는 포크해서 직접 새로운 모양을 만들기 쉽습니다. 처음 카메라 튜토리얼을 따라 설정을 하면 사물이 옆으로 표시되거나 화상이 뒤집혀서 보입니다. 또한, 카메라 마운트가 각각 다르므로 모든 폰마다 이를 테스트해봐야 합니다. 이처럼 카메라를 사용하려면 많은 사례를 고려해 봐야 합니다. Material Camera는 이런 것들을 파악하는데 도움이 됩니다. 비디오도 지원하며, UI도 변경할 수 있습니다. 카메라가 핵심 기능이라면 처음부터 다시 만들어야 할지도 모르지만 그런 상황에도 좋은 참고가 될 수 있습니다.

카메라 기능에 있어 크롭을 제공하는 많은 앱이 형편없었습니다. 스크롤 해서 내려갔는데도 크롭이 가운데로 고정되는 경우도 있었죠. Android Crop은 크롭을 위한 라이브러리로 크롭을 할 수 있도록 간단한 새 액티비티를 제공합니다.

글로벌을 내다보기

안드로이드 개발자로서 전 세계의 개발자를 생각하지 않을 수 없습니다. 세계 각국의 개발자를 위해 개발하는 경우라면 네트워크 에뮬레이션이 중요합니다. 낮은 퀄리티의 네트워크에서도 테스트할 수 있어야 합니다. iOS보다 안드로이드가 어려운데, 네이티브 에뮬레이터인 AVD가 제공되고 있지만 일반적으로 에뮬레이터가 3G인 경우 앱이 잘 작동하지 않는 것 같습니다.

이 경우 Charles proxy가 좋다고 합니다. 컴퓨터에서 프락시를 통과하도록 하는 도구로 설치가 쉽습니다. 다운로드 속도도 지정할 수 있는데, 실제로 얼마나 네트워크가 빠른지 파악하는 것이 어려운 부분입니다. 예를 들어 브라질 3G로 설정을 해도 3G가 브라질 국내에서 속도가 다르기 때문입니다. 아무튼 숫자를 파악한 경우 해당 숫자를 지정할 수 있습니다.

몇 가지 편리한 리소스가 있긴 하지만 네트워크 에뮬레이션 선택이 가장 어렵습니다. 페이스북의 Augmented Traffic Control은 서버에 연결하거나 라우터를 설정한 후 프로파일을 설정할 수 있도록 해줍니다. 비 개발자가 테스트하는 경우라도 이 WiFi 네트워크에 연결해서 연결 레벨을 설정할 수 있습니다. 일반적으로 프로덕트 매니저와 테스터들도 낮은 네트워크 상황을 고려해야 하는데, ATC server를 사용하면 도움이 됩니다.

새로운 안드로이드 O에서 AutoFitTextView와 비슷한 기능을 암시하긴 했지만 아직까지는 텍스트 박스보다 텍스트가 더 큰 경우에는 라이브러리를 사용해야 합니다. 독일어로 번역하는 경우 영어보다 길이가 길어지거나 같은 경우에 더 많은 문자를 사용하므로 박스에 맞게 줄여줍니다. 텍스트 크기를 줄이는 것이 최고의 방법은 아니지만, 화면을 모두 뒤덮게 놔두는 것보다는 나으므로 지역화를 하는 경우 훌륭한 안전 장치가 됩니다.

페이스북의 YearClass는 그해의 가장 최신이 되는 휴대폰을 분류해주는 라이브러리입니다. 2015까지만 제공하긴 하지만, 애널리틱스를 위해 참고할 수 있습니다. 안드로이드 마시멜로우 OS를 올린 폰이라도 기기 자체는 낮은 사양일 수 있으므로 이런 것을 알아두는 것이 도움이 됩니다.

Connection Class는 사용자의 연결 품질을 이해하기 위한 도구입니다. 네트워크를 분류해주며, 4G나 3G가 아닌 다운로드 스피드를 샘플링하고 대역폭을 파악해서 훌륭함, 좋음, 보통, 나쁨, 알 수 없음으로 평가합니다. 그런 다음 평균값을 구해 줍니다. 이런 값을 파악하면 이미지가 많은 사이트인 경우, 품질이 낮은 네트워크에서는 이미지 품질을 낮추거나 미리 가져오기를 최적화하는 등의 작업을 할 수 있습니다.

가장 큰 단점은 샘플링이 좀 어색하다는 점입니다. 시작 샘플링과 종료 샘플링을 제공하는데 실제로 사용자가 앱을 켜고 아무것도 하지 않는다면 네트워크 품질이 나쁘다고 판단합니다. 반면 이미지 등의 네트워크 호출이 많은 경우 인터셉터가 잘 작동하고 작업이 잘 진행됩니다. 하지만 사용자의 네트워크를 파악할 수 있으므로 여전히 추천하고 싶습니다.

다음: 안드로이드의 MVC vs. MVP vs. MVVM

General link arrow white

컨텐츠에 대하여

이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.

Ryan Cooke

Ryan Cooke is an Android Engineer at Pinterest on the Core Experience team. The Core Experience team focuses on among other things making sure Pinterest is using the best libraries available. He was formerly the Lead Android Engineer at UrbanSitter. He has built several additional apps from scratch for freelance and his own personal projects. When not working you can find him skiing, bouldering, playing escape games or looking for his next adventure.

4 design patterns for a RESTless mobile integration »

close