강아지가 귀엽게 짖는 소리와 함께 #AndroidDevChallenge를 시작해볼까요. 강아지 입양 앱을 빌드해보세요! 이 앱에는 강아지 리스트(a list of puppies)를 표시하는 개요 화면과 각 강아지에 대한 세부 정보를 보여주는 세부 화면(detail screen)이 포함되어야 합니다. 3월 2일 23:59 pm 태평양 표준시(한국시간으로 3월 4일 04:59 am)까지 출품하시면 됩니다.

UI는 완전히 Compose로 빌드해야 합니다. 출품작은 오로지 앱의 UI 레이어(layer)를 기준으로 판정됩니다. 레이아웃, 목록, 텍스트, 탐색(navigation)에 관한 Compose 문서를 살펴보면 구현에 도움이 될 것입니다. 시작이 막막하다면, Compose 경로(Compose pathway)를 시도해보시면 어떨까요? 도전 과제를 완료하는데 필요한 다양한 주제를 포함하고 있습니다. 

혹시 🐶보다는 🐱를 좋아하세요? 다른 종류의 반려동물 입양 앱이라도 괜찮습니다. 

여러분들이 어떤 앱을 빌드해주실지 기대가 됩니다! 

이번 주 우승 상품

Compose를 완벽히 구사하여 첫 번째 도전 과제인 반려동물 입양 앱을 멋지게 만든 분께 드릴 상품은 레고 블록으로 만든 한정판 Jetpack Compose 슈퍼히어로 트로피입니다. 이번 도전 과제를 성공적으로 완수해서 출품작을 제출해주신 선착순 500분에게 이 상품을 드립니다. 특별한 트로피와 함께 첫째 주 #AndroidDevChallenge의 수상자가 될 기회를 놓치지 마세요. 

Jetpack Compose 개선 노력에 함께해주세요

커뮤니티는 Jetpack Compose의 중심이며 다음 사항에 관한 여러분의 의견은 더 나은 제품을 만드는 데 큰 도움이 됩니다. 

  • 공식 문제 추적기(issue tracker)에 Jetpack Compose와 관련된 문제를 알려주세요.
  • 등록하신 후 Jetpack Compose 연구에 참여해주세요.

*매주 도전과제마다 새로운 경품이 걸려있습니다. Google Pixel 5를 수령하시는 분 중 Google Pixel 5가 출시되지 않은 국가에 거주하는 분께는 비슷한 금액에 해당하는 기프트카드를 보내드리겠습니다. 자세한 내용은 공식 규정을 확인하세요.



앱 품질(App quality)

앱 품질은 사용자 경험에만 영향을 미치는 것이 아닙니다. 비정상 종료 횟수가 높아지면 다음과 같은 요소도 영향을 받습니다.

  • 앱 발견 가능성(App discoverability) — Google Play 스토어에서 추천하는 앱은 담당자의 선별(human curation)과 알고리즘 계산(algorithmic calculations)이 함께 사용되는데, 이 과정에서 앱 품질이 큰 부분을 차지합니다.
  • 브랜드(Brand) — 제품 성능은 평가(ratings)와 리뷰(reviews)에 영향을 주고, 이로 인해 브랜드 이미지도 영향 받을 수 있습니다.
  • 더 많은 사용자와 높은 참여도(Higher number of (engaged) users) — 향상된 자연 트래픽(organic traffic)과 브랜드 인지도(brand perception)를 바탕으로 사용자 획득(user acquisition)과 유지율(retention)을 높이고, 이를 통해 사용자 참여(engagement)와 하위 유입경로 측정항목(lower funnel metrics)도 개선할 수 있습니다.

Kotlin으로 빌드한 앱은 비정상 종료 발생 확률이 20% 낮습니다.


여기서 Kotlin은 어떤 역할을 할까요? Google Play의 상위 1,000개 앱을 살펴본 결과, Kotlin을 사용하는 앱은 다른 앱보다 사용자당 비정상 종료(crashes)가 20% 더 적은 것으로 나타났습니다.

코드의 74%를 Kotlin으로 작성하는 Swiggy 엔지니어링팀의 사례를 살펴보면, 새로운 기능 개발에 Kotlin을 사용한 이후로 비정상 종료가 50% 감소했습니다.



NullPointerException 방지하기(Avoiding NullPointerExceptions)

Google Play에서 비정상 종료의 가장 큰 원인은 NullPointerException입니다. 2018년부터 Google Home팀에서는 모든 새 기능을 Kotlin으로 개발하기 시작했으며, 1년 동안 Null 포인터 비정상 종료가 33% 감소하는 성과를 얻었습니다.


Google Home은 NullPointerException가 33% 감소했습니다.


NullPointerException을 방지하려면 메서드를 호출하거나 멤버에 액세스하기 전에 작업 중인 객체 참조가 null이 아닌지 확인해야 합니다. Kotlin에서 null 허용 여부는 유형 시스템의 일부입니다. 예를 들어, 변수는 처음부터 null 허용 또는 null을 허용하지 않음으로 선언되어야 합니다. null 허용 여부를 유형 시스템의 일부로 만들면 메모리과 코드베이스 지식 또는 컴파일 시간 경고(필드/매개변수에 @Nullable로 주석을 남기는 경우)에 의존할 필요 없이, null 허용 여부가 적용됨에 따라 경고뿐만 아니라 컴파일 시간 오류도 표시됩니다. null 허용 여부를 처리하는 방법은 이 페이지에서 확인하세요.



일반적인 문제 방지하기(Avoiding common issues)

개발자가 자신도 모르게 일으키는 문제가 많은데, 그중 상당수는 아주 미묘하고 파악하기 어렵습니다. 다음은 Kotlin 사용으로 방지할 수 있는 문제의 몇 가지 예입니다.

hashCode() 및 equals()

두 객체가 같다면 해시코드도 같아야 합니다. 그런데 이러한 메서드 중 하나를 구현하지 않거나 클래스에 새로운 속성이 추가되었을 때 업데이트하지 않는 경우가 자주 있습니다. 데이터를 보관하는 역할을 하는 클래스로 작업할 때는 Kotlin data class를 사용하세요. data class를 사용하면 컴파일러에 의해 hashCode() 및 equals()가 생성되며 클래스의 속성을 변경하면 자동으로 업데이트됩니다.



구조 동등성(Structural equality)과 참조 동등성(referential equality)

두 객체가 구조적으로 동일(동일한 내용을 가짐)하거나 참조적으로 동일(포인터가 동일함)하나요? 자바 프로그래밍 언어에서 기본 유형에 항상 == 기호를 사용하므로, 구조적으로 동등한지 확인(equals()를 호출하여 확인)하려는 경우에도 객체에 ==(참조 동등성) 를 호출하는 실수를 흔히 하게 됩니다. 첫째로 Kotlin에는 기본 유형(primitive types)이 없고 Int 또는 String 등의 클래스를 사용하므로 더 이상 객체와 기본 유형을 구분할 필요가 없습니다. 모두 객체이기 때문입니다. 둘째로 Kotlin에서는 == 기호를 구조 동등성으로, === 기호를 참조 동등성으로 정의하므로 구조 동등성을 확인해야 할 때 참조 동등성을 확인할 일이 없습니다.



if else의 반복사용으로도 충분하지 않은 경우

enum으로 작업할 때는 가능한 모든 케이스를 다루고 있는지 확인해야 할 때가 많습니다. 그로 인해 switch나 일련의 if else를 사용하게 됩니다. 새 값을 추가하기 위해 enum을 수정하는 경우에는 enum을 사용 중인 각 코드 스니펫을 수동으로 확인하며 새로운 케이스를 처리하는지 확인해야 합니다. 그러나 이 과정에서 쉽게 오류가 발생합니다. Kotlin에서는 이 작업에 컴파일러를 활용(rely on the compiler)할 수 있으며 when표현식을 사용할 수 있습니다. 가능한 모든 케이스를 다루고 있지 않을 경우 컴파일러 오류가 발생합니다.


결론

앱의 안정성은 사용자와 브랜드 모두에 중요합니다. Kotlin 사용을 시작하여 비정상 종료 발생률을 낮추고 만족스러운 사용자 경험을 제공하세요. 높은 앱 평점을 유지하여 사용자 획득과 유지율 측면에서도 좋은 성과를 낼 수 있습니다.

Kotlin으로 더 나은 앱 만들기에서 자세한 내용을 읽어 보고 우수 사례에서 Kotlin이 개발자에게 어떤 이점을 가져다 주는지 확인해 보세요. Kotlin전 세계의 많은 개발자에게 사랑받는 언어입니다. 첫걸음을 내딛는 데 도움을 받으려면 시작하기 페이지를 확인하세요.