https://play.google.com/apps/test/<package name>/<version code>
この記事は Florina Muntenescu による Android Developers Blog の記事 "MAD Skills Kotlin and Jetpack: wrap-up" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
今回は MAD Skills シリーズの 1 つ、Kotlin と Jetpack についての動画と記事をまとめました。Android コードの表現力と簡潔さ、安全性を向上させ、Kotlin で非同期コードを実行しやすくするさまざまな方法を取り上げています。
それぞれのエピソードから、Kotlin と Jetpack についての最新情報をご確認ください。いくつかの具体的な API を取り上げ、API の使い方だけでなく、API が内部的にどのように動作しているか解説しています。また、すべてのエピソードには対応するブログ投稿があり、そのほとんどにサンプルか Codelab へのリンクが含まれているので、実際に試してみたり、コンテンツに関する理解を深めたりできます。また、Jetpack や Kotlin のエンジニアが登場するリアルタイム Q&A も実施しました。
このエピソードでは、Jetpack KTX 拡張機能を使って、Android と Jetpack のコーディングを簡単、快適、そして Kotlin らしくする方法を取り上げました。現在のところ、20 以上のライブラリに KTX 版があり、その中から特に重要なものを紹介します。core-ktx は、Android プラットフォームに由来する API を Kotlin らしく書けるようにする機能を提供しています。また、LiveData や ViewModel などの API と組み合わせてユーザー エクスペリエンスの向上を図れるいくつかの Jetpack KTX ライブラリも紹介します。
動画またはブログ記事(英語)をご覧ください。
エピソード 2 では、コルーチンと Flow を使って API をシンプルにする方法と、suspendCancellableCoroutine API と callbackFlow API を使って独自のアダプタを作る方法について説明します。このトピックを実際に試してみたい方は、Kotlin 拡張機能ライブラリの作成 Codelab をご覧ください。
動画を視聴するか、ブログ記事(英語)でご確認ください。
このエピソードでは、実際に Room を使ってみます。その上で、Kotlin を使って Room のテーブルやデータベースを作る方法、挿入などの 1 回限りの suspend 操作を実装する方法、Flow を使った監視可能クエリーについて簡単に確認します。コルーチンと Flow を使うと、Room はすべてのデータベース操作をバックグラウンド スレッドに移してくれます。Room のクエリーの実装方法やテスト方法については、動画またはブログ記事(英語)をご覧ください。実際に試してみたい方は、ビューで Room を使う Codelab をご覧ください。
エピソード 4 では、WorkManager を使って作業を簡単にする方法について説明します。この機能を使うと、非同期タスクのスケジュールを設定して、アプリが閉じられた場合や、デバイスが再起動した場合にも実行されることが期待されるタスクを、即時実行または遅延実行できます。このエピソードでは、WorkManager の基本について説明し、CoroutineWorker などの Kotlin API についても解説しています。
こちらの動画またはこちらのブログ記事(英語)をご覧ください。また、ぜひ WorkManager Codelab で実際に体験してみてください。
エピソード 5 では、Android の Google Developer Expert の Magda Miu さんが Kotlin の基本 API と CameraX を使った経験についてお話ししています。
最後のエピソードでは、リアルタイム Q&A を実施しました。司会の Chet Haase のほか、ゲストとして Architecture Components テックリードの Yigit Boyar、Kotlin プロダクト マネージャーの David Winer、そしてデベロッパー リレーションズ エンジニアの Manuel Vivo と私が参加し、YouTube、Twitter などから寄せられた質問に回答しています。
Reviewed by Yuichi Araki - Developer Relations Team and Hidenori Fujii - Google Play Developer Marketing APAC
この記事は Florina Muntenescu による Android Developers - Medium の記事 "More productivity with Kotlin" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Kotlin は簡潔なプログラミング言語として知られています。そしてそれは、高い生産性を意味します。そして実際に、Kotlin を使っている Android デベロッパーの 67% が、生産性が向上したと述べています。このブログ投稿では、Kotlin を使ってパートナーのエンジニアたちが生産性を向上させた方法をいくつか共有し、そのために役立つ Kotlin の機能も紹介します。
レビューやメンテナンスの担当者は、読むコードが少なくなるので、コードが行っていることを理解しやすくなります。そのため、レビューやメンテナンスが楽になります。
その一例として、Flipkart のチームを紹介しましょう。
「弊社の社内調査によると、デベロッパーの 50% が、Kotlin でモジュールを書くと [機能を完成させるまでの] 見積りが小さくなると回答しました」(Flipkart)
Kotlin の機能のほとんどは、簡潔さと高い可読性を持つため、高い生産性につながります。特によく使われる機能について見てみましょう。
Java プログラミング言語では、コンストラクタのパラメータが省略可能な場合、一般的に次の 2 つの方法のどちらかを利用します。
Kotlin ではデフォルト引数を利用できるので、どちらも必要ありません。デフォルト引数を使うと、ボイラープレートを追加することなく、関数のオーバーロードを実装できます。
Cash App チームが Kotlin を使い始めたとき、多くのビルダーを削減し、書く必要があるコードの量を減らすことができました。場合によっては、コードのサイズが 25% 少なくなりました。
たとえば、以下の一例は、 Task オブジェクトの実装で、タスクの名前のみが必須パラメータになっています。ビルダーを使った場合と、デフォルト引数を使った場合でそれぞれどうなるかを示しています。
/* Copyright 2020 Google LLC. SPDX-License-Identifier: Apache-2.0 */- public class Task {- private final String name;- private final Date deadline;- private final TaskPriority priority;- private final boolean completed;-- private Task(String name, Date deadline, TaskPriority priority, boolean completed) {- this.name = name;- this.deadline = deadline;- this.priority = priority;- this.completed = completed;- }-- public static class Builder {- private final String name;- private Date deadline;- private TaskPriority priority;- private boolean completed;-- public Builder(String name) {- this.name = name;- }-- public Builder setDeadline(Date deadline) {- this.deadline = deadline;- return this;- }-- public Builder setPriority(TaskPriority priority) {- this.priority = priority;- return this;- }-- public Builder setCompleted(boolean completed) {- this.completed = completed;- return this;- }-- public Task build() {- return new Task(name, deadline, priority, completed);- }- }-}+ data class Task(+ val name: String,+ val deadline: Date = DEFAULT_DEADLINE,+ val priority: TaskPriority = TaskPriority.LOW,+ val completed: Boolean = false+)
/* Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
- public class Task {
- private final String name;
- private final Date deadline;
- private final TaskPriority priority;
- private final boolean completed;
-
- private Task(String name, Date deadline, TaskPriority priority, boolean completed) {
- this.name = name;
- this.deadline = deadline;
- this.priority = priority;
- this.completed = completed;
- }
- public static class Builder {
- private Date deadline;
- private TaskPriority priority;
- private boolean completed;
- public Builder(String name) {
- public Builder setDeadline(Date deadline) {
- return this;
- public Builder setPriority(TaskPriority priority) {
- public Builder setCompleted(boolean completed) {
- public Task build() {
- return new Task(name, deadline, priority, completed);
-}
+ data class Task(
+ val name: String,
+ val deadline: Date = DEFAULT_DEADLINE,
+ val priority: TaskPriority = TaskPriority.LOW,
+ val completed: Boolean = false
+)
デフォルト引数の詳細については、連載シリーズ Kotlin Vocablary のブログ記事「Kotlin のデフォルト引数」をご覧ください。
おそらく、シングルトン パターンはソフトウェア開発で特によく使われるパターンの 1 つでしょう。オブジェクトのインスタンスを 1 つだけ作成し、他のオブジェクトから共有してアクセスできるようにしたい場合に役立ちます。
シングルトンを作るには、インスタンスが 1 つだけ存在するようにオブジェクトの作成方法を制御し、コードがスレッドセーフであることを保証する必要があります。Kotlin では、object キーワードだけでこれを実現できます。
/* Copyright 2020 Google LLC. SPDX-License-Identifier: Apache-2.0 */ - public class Singleton{- private static volatile Singleton INSTANCE;- private Singleton(){}- public static Singleton getInstance(){- if (INSTANCE == null) { // Single Checked- synchronized (Singleton.class) {- if (INSTANCE == null) { // Double checked- INSTANCE = new Singleton();- }- }- }- return INSTANCE;- }- private int count = 0;- public int count(){ return count++; }- }+ object Singleton {+ private var count = 0+ fun count(): Int {+ return count+++ }+ }
- public class Singleton{
- private static volatile Singleton INSTANCE;
- private Singleton(){}
- public static Singleton getInstance(){
- if (INSTANCE == null) { // Single Checked
- synchronized (Singleton.class) {
- if (INSTANCE == null) { // Double checked
- INSTANCE = new Singleton();
- return INSTANCE;
- private int count = 0;
- public int count(){ return count++; }
+ object Singleton {
+ private var count = 0
+ fun count(): Int {
+ return count++
+ }+ }
Kotlin 言語の簡潔さとシンプルさは、演算子オーバーロード、分割代入、文字列テンプレートなどの機能から明らかです。そのため、コードはとても読みやすくなります。
たとえば、本を集めたライブラリがあるとしましょう。ライブラリから本を取り出し、そのタイトルだけを出力する場合、コードは次のようになります。
/* Copyright 2020 Google LLC. SPDX-License-Identifier: Apache-2.0 */fun borrow(){ library -= book val (title, author) = book println("Borrowed $title")}
fun borrow(){
library -= book
val (title, author) = book
println("Borrowed $title")
}
使われている Kotlin の機能は次のとおりです。
Kotlin を使うと、コードは読みやすく、書きやすくなります。シングルトンや委譲などのパターンが言語に組み込まれており、たくさんのコードを書く必要がないため、バグが紛れ込む確率が低くなり、メンテナンスの負荷も軽減されます。また、文字列テンプレート、ラムダ式、エクステンション関数、演算子オーバーロードなどの機能で、コードをさらに簡潔かつシンプルにできます。書くコードが少なくなれば、読むコードやメンテナンスするコードも少なくなり、エラーが減って生産性が上がります。
詳しくは、Kotlin と Android Kotlin でより優れたアプリを作成するをお読みください。また、各社のケーススタディをご覧ください。デベロッパーにとっての Kotlin のメリットが確認できます。世界で特に好まれている開発言語の 1 つである Kotlin を使ってみたい方は、入門ページをご覧ください。
この記事は Eric Bahna による Android Developers Blog の記事 "Opening the Google Play Store for more car apps" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
2020 年 10 月、Android Auto にナビゲーション、駐車場、充電スポット アプリを提供できるよう、ベータ版として Android for Cars App Library を公開しました。改善のため、これまでフィードバックを寄せていただいた皆様には改めて感謝いたします。そしてこのたび、次のステップに進む準備が整ったことをお知らせします。
2020 年 12 月 16 日(日本時間 12 月 17 日)より、Google Play ストアのクローズドなテストトラックにアプリを公開できるようになりました。この機能を使うと、アプリがどの程度アプリ品質ガイドラインを満たしているかについてのフィードバックを得られます。また、アプリを Android Auto テストユーザーに体験してもらう方法としても利用できます。継続的に問題が発生する場合は、パブリック Issue Tracker から問題の報告や機能リクエストを行ってください。
まもなく Play ストアのオープンテスト トラックが公開できるよう準備をしています。ぜひ、事前にクローズド テストトラックにアプリを公開してお待ちください。多くのデベロッパーのみなさんが開発した自動車用アプリがリリースされるのを楽しみにしております。
この記事は Christopher Katsaros による Android Developers Blog の記事 "What’s your MAD score?" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
MAD Skills シリーズを通して最先端の Android 開発(MAD)についてさまざまなことをお話ししてきました。そして今回は、皆さんの MAD スコアについてお知らせします。2020 年 12 月 15 日(日本時間 12 月 16 日)、MAD スコアカードを公開しました。これは、皆さんが使っている Jetpack ライブラリの数や、Kotlin でコーディングしているアプリの割合などを使い、皆さんの Andorid 開発がどれだけ最新であるかを示すスコアです。
MAD スコアカードは Android Studio を使って、アプリが Android App Bundle でどれくらいサイズを削減したかなどの情報を示します。また、特定の Jetpack ライブラリや Kotlin 機能など、皆さんが使う可能性がある主要な MAD テクノロジーにもそれぞれスポットライトを当てています。さらに、皆さんの最も MAD なスキルに基づいて、特別な MAD キャラクターも表示されます。
ご自身の MAD スコアは、新しい Android Studio プラグインを通じて確認できます。スコアカードを確認して共有する方法は、以下のとおりです。
スコアカードを確認できたら、MAD Skills の各エピソードもご覧ください。この動画と記事のシリーズでは、最先端の Android 開発の最新技術を使って、優れたアプリを簡単に作る方法を説明しています。ナビゲーション、Kotlin、Android Studio などの各トピックは、3 週間のシリーズとして構成されています。各トピックの最後には、Q&A で皆さんの質問に回答します。マテリアル デザイン コンポーネント、App Bundle、ナビゲーションなど、以前のトピックも確認できます。今後のトピックは、YouTube の Android Developers で公開します。
ここから MAD スコアカードを確認して、共有しましょう!
Reviewed by Hidenori Fujii - Google Play Developer Marketing APAC
この記事は Chet Haase による Android Developers - Medium の記事 "Now in Android #31" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Android 開発の最新ニュースやトピックをご紹介する Now in Android。今回は連載シリーズ MAD Skills のコンテンツ、最近公開されたブログ記事・動画・関連ドキュメント、ポッドキャスト エピソードなどをご紹介します。
MAD Skills シリーズに少しインタラクティブ性をもたせ、あなたのアプリがどのくらい MAD か、スコアで可視化できるようになりました。あなたの MAD スコアを確認するには、Android Studio に MAD Scorecard プラグインをインストールして実行します。すると、カードが作成され、最先端の Android 開発の大事な 4 つのトピックにおいて、皆さんのアプリを評価したスコアが表示されます。この結果は、 #MADscore ハッシュタグを付けて Twitter で共有できます。
詳しくは、MAD Score サイトをご覧ください。Christopher Katsaro のブログ記事(英語)でも詳しく説明しています。
最先端の Android 開発に関する技術コンテンツを扱う連載シリーズ MAD Skills が続いています。先週は、マテリアル デザイン コンポーネント (MDC) のシリーズが完結しました。前回の Now in Android 以降、さらに 3 つのエピソードが投稿されています。
#4: マテリアル モーション
MDC 4 つ目のエピソードでは、Nick Rout がマテリアルに動きをつける 4 つのパターンと、アプリでそれを実装する方法についてお話ししています。実際の活用例を紹介するため、Reply サンプルアプリとそのアプリに基づいた Codelab を題材に解説します。
#5: Zarah Dominguez さんからのコミュニティ ヒント
5 つ目の MDC エピソードは、Google Developer Expert の Zarah Dominguez さんが、チームでマテリアル カタログアプリを使って、各コンポーネントが実際にどのような外観になるか、またその実装例としてどのようなソースコードになるかの両方を確認している方法について説明しています。
#6: リアルタイム Q&A
最後の MDC エピソードは、これまでの App Bundle やナビゲーションのシリーズと同じく、MDC のエキスパートであるデベロッパー リレーションズ チームとマテリアル エンジニアリング チームが登場して、リアルタイム Q&A を行いました。Twitter からだけでなく、Q&A の最中も YouTube からリアルタイムで質問が寄せられました。すべてに答える時間はありませんでしたが、マテリアルについて理解を深めていただけたのではないかと思います。
MDC シリーズのコンテンツを見逃してしまった方のために、Nick Rout がシリーズのまとめのブログ記事を投稿しました。対応する動画や記事に加え、関連するサンプルやドキュメント、Codelab などへのリンクも含まれています。
12 月 第 3 週から、Kotlin と Jetpack について取り上げる新しい MAD Skills のミニシリーズが始まりました。具体的には、Kotlin と多くの Jetpack API を組み合わせて使う方法について、Florina Muntenescu が紹介しています。
#1: Using KTX
ミニシリーズ最初のエピソードで取り上げるのは、KTX の使い方です。KTX は、さまざまなプラットフォームや Jetpack ライブラリに対するアプローチを改善して簡単に使えるようにした Kotlin エクステンションです。Florina が、プラットフォームと Jetpack API の両方の例を挙げて、LiveData と ViewModel を利用する場合の使い方を示しながら、KTX の概要について説明します。
このコンテンツはブログ記事(英語)でもご覧いただけます。
#2: コルーチンで API をシンプルに
この 2 つ目のエピソードでは、Manuel Vivo が、Kotlin コルーチンを使って既存の API を簡単に利用できるようにする方法について説明します。たとえば、コルーチンを使ってアダプタを作成すれば、複雑にネストしたコールバックをシンプルに整理できます。Fused Location Provider を使うための API をシンプルにする例を挙げ、実際にこれを行う方法を解説します。
ブログ記事形式(英語)でもご覧いただけます。
これからの数週間で公開される Kotlin/Jetpack エピソードにご期待ください。YouTube プレイリストと Android Developers のブログ記事(英語)のどちらでもご覧いただけます。
連載中のコンテンツは、YouTube の MAD Skills プレイリスト、Medium の記事、またはすべてのリンクが掲載されている 便利なランディング ページ からご確認ください。
最近数回実施している Android のリリースでは、ユーザーによる制御やユーザーデータの透過性を重視することを続けているため、権限に関するいくつかの変更が行われています。場合によっては、最新のアップデートや動作の変更に追従するというデベロッパーの作業も伴います。そのため、そのプロセスをサポートするドキュメントの整備に取り組んでいます。
この作業の一環として、 Android の権限ガイドにいくつかの重要な改善を行いました。権限の仕組みに関するわかりやすいガイドのほか、アプリで権限を使う際のベスト プラクティスを確認できるようになりました。特に重要なのは、実際に権限の宣言が 必要かどうかを評価することです。多くの一般的なユースケースでは、権限は必要ではありません。
いくつかの Room ライブラリ ガイドを全面的に改訂し、一部の API の使い方をわかりやすく説明するようにしました。
Room DAO を使用してデータにアクセスするでは、組み込みのクエリーを使う方法や、@Query アノテーションを使うカスタムの方法など、DAO インターフェースの使い方の概要を説明しています。
Write asynchronous DAO queries では、UI スレッド以外で実行するクエリーの書き方についてさらに詳しく説明しています。データベースを操作する場合、この方法が求められることが非常に多くあります。このガイドでは、好みの言語や非同期 API に応じて利用できるいくつかの代替手段についても解説しています。
最近たくさんのアルファ版、ベータ版、RC 版の AndroidX ライブラリがリリースされましたが、安定版のリリース内容は次のとおりです。
Exifinterface 1.3.2、Media 1.2.1、Navigation 2.3.2 など、いくつかの安定版でもバグ修正リリースが行われています。
Jamal Eason が Android Studio の次期リリースについてのブログ記事(日本語)を投稿しました。現在、Canary チャンネルに Arctic Fox がリリースされ、試せるようになっています。このリリースについてまず注目すべき点は、新しい命名スキームとバージョニング スキームです。この記事では、その内容について詳しく説明しています。さらに、このリリースには、デバイスとペア設定して Wi-Fi デバッグを行うための UI(現在のところ MacOS のみ)、レイアウト検証ツール、継続的に行われている Jetpack Compose 開発のサポートなどが含まれています。なお、現段階のバージョンはかなり初期の状態です。Compose を利用する場合は常に Canary 版の Studio を使う必要がありますのでご注意ください。
Murat Yener も、新しい Android Studio に関するブログ記事(日本語)を投稿しました。この記事では、Android Gradle プラグインの新しいアルファ版リリースであるバージョン 7.0.0-alpha01 について説明しています。なお、AGP もバージョン名が変更されました。今後、AGP は Android Studio のバージョンと連動するのではなく、Gradle のリリース バージョンに追従する形になります。現在の 4.2 リリースからいくつかバージョン番号が飛んでいるように見えるのは、そのためです。この記事では、AGP 4.2 における最新 API のいくつかの変更点についても説明しています。
Meghan Mehta が、RecyclerView についてのシリーズにブログ記事を投稿(英語)しました。RecyclerView は新しいものではありませんが、おそらく、ほとんどの Android デベロッパーはすでにアプリで使っているはずです。一部の基本的なドキュメントやサンプルがドキュメントや記事の中で見つけにくいことがわかったので、基本から使い方を説明しています。さらに、実例を示すためのサンプルコードも提供します。
この最新記事では、ListAdapter の使い方を重点的に説明します。ListAdapter を使うと、パフォーマンスの向上や項目の自動アニメーションなどのすばらしい機能を RecyclerView で簡単に実現できます。ListAdapter は DiffUtil を使って発生した具体的な変更を確認します。RecyclerView は、それを使ってパフォーマンスやアニメーションを最適化します。
私は引き続き、最近 1.0 に到達した AndroidX ライブラリである App Startup についての 2 回シリーズの記事(英語)で、起動時のパフォーマンスについて説明しています。パート 1 では、ライブラリのインスタンス化に Content Provider が使われることが多く、それによってアプリの起動時間に見えない影響が生じている点について説明しました。
パート 2 では、App Startup ライブラリを使って見えない Content Provider を取り除き、代わりにライブラリの遅延初期化リクエストをプーリングする方法について検討します。
Android Developers ブログには、位置情報のシステムと API に加えた改善について詳しく説明した記事(日本語)が投稿されています。この改善により、都市部で正確な位置情報を得られるようになります。この記事では、都市部で GPS 位置情報を取得する際の問題点について説明しています。GPS テクノロジーは、デフォルトで対象が見通し線上にあることを前提としているので、信号が高層ビルで反射する都市部ではうまく機能しない場合があります。Tor と私は、2014 年の ADB ポッドキャストで、位置情報チームの Marc Stogaitis から、「アーバン キャニオン」と呼ばれるこの現象について話を聞きました。
このチームは、精度の高い位置情報を得るために、主要都市の 3D 建造物モデルを統合しました。現在、一部の Pixel デバイスでこの技術のバージョン 2 を利用できます。初期バージョンはすでにエコシステムで広く使われており、来年の早いうちにこの最新バージョンも利用できるようになる予定です。
もちろん、この機能はユーザー機能で、Now in Android はデベロッパーが対象です。しかし、ここでこの機能を紹介したのは、(a)この記事と技術は興味深く、(b)デベロッパーは Fused Location Provider(FLP)を使って高度な位置情報データにアクセスすることが求められる場合があるからです。
さらに、FLP に新しい API が追加され、現在の位置情報をはるかに簡単に取得できるようになっています。具体的には、位置情報の変化をサブスクライブして最初の結果が得られたときにサブスクライブを解除するのではなく、現在の位置情報をリクエストして結果を得ることができます。詳しくは、FLP の getCurrentLocation() API のドキュメント、新しい CurrentLocationKotlin のサンプル、そしてブログ記事をご覧ください。
Chris Banes は、Tivi アプリを現在の UI Toolkit を使うアプリから、Jetpack Compose を使うアプリに移行しています。すべての UI を Compose 化し、移行作業の大部分を終えたところで、APK サイズ(大幅に減少)、メソッド数(減少)、ビルド時間(少し減少)について興味深い結果をブログ記事(日本語)で報告してくれました。
CameraX の CameraView API は、UI の制御から制御ロジックまで、あまりに多くのことを行い過ぎていました。そこで、ロジックをリファクタリングし、PreviewView と新しい CameraController クラスに分割しました。このブログ記事(英語)では、CameraController の使い方を説明するとともに、これまでの CameraView を使った機能との比較を行っています。
前回の Now in Android 以降、Android Developers Backstage に新しいエピソードが投稿されています。以下のリンクまたはお気に入りのポッドキャスト クライアントでご確認ください。
Romain Guy、Tor Norbye と私は、Square の Jesse Wilson 氏から、OkHttp、Okio、[Ok]Moshi など、同氏が手がけたいくつかの有名なオープンソース ライブラリについて話を聞きました。これらのライブラリのほかにも、Android、ライブラリ、フレームワーク、Kotlin 開発について語り合っています。また、機能リクエストや細かな問題を新しいオープンソース ライブラリを作るプロジェクトにしてしまう一部のエンジニアの厄介な癖に関する話題も登場しました。
今回は以上です。次回も Android デベロッパーの世界の最新アップデートをお届けします。お楽しみに。
Reviewed by Takeshi Hagikura - Developer Relations Team and Hidenori Fujii - Google Play Developer Marketing APAC
この記事は Chris Banes による Android Developers - Medium の記事 "Jetpack Compose — Before and after" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
今年になってから、サンプル アプリTivi の UI を Jetpack Compose に徐々に移行していました。そして 2020 年 12 月第 2 週、移行作業の第一段階がほぼ完了しました。
今回のブログ投稿では、重要な指標の数値を振り返って比較し、Compose によって何が変わるのかを確認してみましょう。比較するのは、APK サイズ、ビルド速度、コードの行数です。
Compose の話題を進める前に、まずは簡単にアプリについて説明します。
Tivi はかなり細かくモジュール化されており、それぞれの UI の「画面」ごとに Gradle モジュール(ui-$NAME)があります。それぞれの画面は Fragment で実装され、メインアプリ モジュールでは AndroidX Navigation を使ってそれらを組み合わせています。
ナビゲーション グラフはディープリンク URI を使って実装されているので、ほとんどの Fragment はお互いのことを知りません。そのため、疎結合が保証されます。しかし、それよりも重要なことは、独立してコンパイルできるため、ビルドの並列化がしやすくなることでしょう。
Compose に移行する前の Tivi は、Android デベロッパーが利用できるありとあらゆるクールな UI を利用していました。一例をあげれば、データ バインディング、Epoxy、マテリアル デザイン コンポーネント、Insetter DBX、MotionLayout などです。しかし残念ながら、これらの大半ではアノテーション処理が使われているため、ビルドのコストがかかります。
先ほど、移行の「第一段階」を終えたばかりだと書きました。これはどういう意味でしょうか。2020 年 1 月にこの作業を始めたときから、アプリの見た目はほとんど変わっていません。
アプリがモジュール化されているということは、移行自体も部品単位になり、一度に 1 つの Fragment だけ移行できるということです。この 11 か月間はまさにそれを実践し、46 個のプル リクエストに対応しています。
最初に簡単な画面 Episode details を移行し、次に Show details、そして ‘Discover’、‘Search’、‘Followed shows’ と移行を進めました。最近追加された Compose の Paging3 サポートと合わせて、最後の画面となった ‘list’ グリッドを移行できました。
2020 年 12 月 10 日(日本時間 12 月 11 日)、アプリから AppCompat、マテリアル デザイン コンポーネント、その他の AndroidX ウィジェット ライブラリを削除する処理を始めました。これは、Tivi の UI が Compose ベースになったことを意味します。
Remove AppCompat + MDC by chrisbanes · Pull Request #737 · chrisbanes/tivi
アプリで Fragment と Navigation を使っている点は変わりませんが、論理的な次のステップは、Fragment から移行して直接新しい Navigation Compose コンポーネントを使うようになります。
この移行の過程は近日中に別のブログ記事で書きたいと思いますが、本投稿の最後の「まとめ」から、私自身の言葉を引用しておきます。
いろいろ考えなくても、Compose が Android の UI 開発の未来であることはわかります。
では、いくつかの指標を確認してみましょう。
以下のそれぞれの指標では、3 つのバージョンのアプリを比較します。
ユーザーが最も気にする指標は、APK サイズです。
以下の結果は、リソース圧縮を有効にし、R8 を使って最小化した release APK を APK Analyzer で測定したものです。
‘adjusted’(調整済み)の値と ‘Pre-Compose’ を比較すると、Compose を使った場合は APK サイズが 41%、メソッド数は 17% 削減されていることがわかります。
Compose を使った場合は、APK サイズが 41%、メソッド数は 17% 削減されていることがわかる
この数から、AppCompat や MDC などがアプリ内でどれほどの容量を占めているかがわかります。それだけではなく、レイアウト ファイルで使われる場合に備えてすべての View クラスを保持しなければならない場合には、最小化ツールはほとんど役に立たないこともわかります。
ソフトウェア プロジェクトを比較する場合、ソースの行数を数えても特に役立つ統計情報にはならないことは承知していますが、この比較によって、どのような変化が起きているのかは確実に把握できます。
このテストでは、cloc ツールで以下のコマンドを使い、すべてのビルドと生成されたファイル、設定ファイルを除外しました。
cloc . --exclude-dir=build,.idea,schemas
cloc ツールにはコメントを無視する機能が組み込まれているので(ただし、検証はしていません)、上記は実際の「コード」の結果です。当然ながら、XML の行数は大幅に少なくなり、76% 削減されています。レイアウト ファイル、スタイル、テーマなど、たくさんの XML ファイルとお別れできます。
同じように興味深いのは、Kotlin の合計行数も減っていることです。仮説としては、アプリ内のボイラープレートが減り、たくさんのビューヘルパーやユーティリティ コードを削除できたためだと考えられます。3,000 行近くを削除できたこちらの PR をご覧ください。
Remove a load of old code 🗑️ by chrisbanes · Pull Request #713 · chrisbanes/tivi
ビルド速度はデベロッパーの関心が非常に高い指標です。このプロセスを開始する前は、多くのアノテーション プロセッサを削除できることでビルド速度が向上するものと考えていましたが、どの程度かはよくわかりませんでした。
テストの設定
説明を続ける前に、以下の数値をどのようにして測定したのかを知っておくことが重要になります。ここでは、Chris Horner が異なる CPU でビルド速度を測定したときと同じ設定を使いました。
テストに使ったマシンは、192 GB の RAM と超高速な Xeon® Gold 6154 CPU を搭載した Lenovo P920 です。言うまでもなく、このマシンは一般的なデベロッパーの設定ではありません。そこで、現実に近いテストを行うため、CPU を最低クロック周波数に固定しました。
# Use performance governor to allow tweaking of max freq
sudo cpupower frequency-set -g performance
# Set max frequency to CPU minimum: 1.2GHz
sudo cpupower frequency-set -u 1.2GHz
その後、すべてのリモート アーティファクト キャッシュを準備するため、./gradlew assembleDebug を実行しました。
そして、テストを実行するため、次のコマンドをループで 5 回実行します。
./gradlew --profile \
--offline \
--rerun-tasks \
--max-workers=4 \
assembleDebug
厳密には --max-workers は必要ありませんが、この CPU では、デフォルトで Gradle が利用できる 64 個の「コア」のすべてが使われます。これを 4 に制限することで、通常のラップトップ CPU と比較しやすくします。
テスト結果は以下のとおりです。それぞれの結果プロファイル レポートの ‘Total Build Time’(合計ビルド時間)の値をご覧ください。
この結果にはかなり驚かされました。ほとんど数値が変わらなかったからです。予想では、多くのアノテーション プロセッサが削除されることで、‘Without view libs’(ビュー ライブラリなし)が大幅に速くなると思っていました。
結果の明細を見てみると、kapt の実行時間はすべて同じくらいでした。おそらくこれは、View Binding、Dagger/Hilt、Room の使用を継続しているためではないかと思います。
しかし、Kotlin コンパイラや Compose コンパイラ プラグインが行ってくれることを考えれば、ビルド時間が 5% 削減されたことに何も不満はありません。
これまでに説明してきた全ての結果に当てはまる注意点があります。
この 11 か月間、Tivi には何の機能も追加しませんでしたが、この点を厳密に制限したわけではありません。移行とはあまり関係のない部分で多くの変更を行っており、それが結果に影響した可能性もあります。
移行を行った 11 か月間で、多くの依存性が更新されました。ほとんどの依存性の更新はランタイム ライブラリの依存性だったので、APK サイズ指標に影響する可能性は低いはずです。
Gradle のアップデート(6.0.1 から 6.7.0)、Android Gradle Plugin のアップデート(3.6.0 から 4.2.0)、そして Kotlin のアップデート(1.3.61 から 1.4.20)などは、すべてビルド速度に大きな影響があります。
Compose は現在アルファ版なので、すべての成果物は開発中のスナップショットになります。来年 1.0 の安定版になったとき、これらのテストを再実行して違いが出るかを見るのが楽しみです。
結果と注意点を見る限り、リンゴ 🍎 とリンゴ 🍏 を比較しているわけではない(同じ条件で比較しているわけではない)ので、あまり多くの結論を出すべきではありません。これは、リンゴ 🍎 とそれよりも少し甘いナシ 🍐 を比べているようなものです。
果物の例はさておき、最大のポイントは Compose がほとんどのデベロッパー指標で良好な(または中立的な)影響を示していることです。この点と Compose でデベロッパーの生産性が大幅に向上することを踏まえれば、いろいろ考えなくても、Compose が Android の UI 開発の未来であることはわかります。
個人や小規模グループでゲームを開発するデベロッパーの情熱やイノベーションを称えるため、今年 3 年目となる Google Play | Indie Games Festival 2020 を開催しました。例年のようにファイナルイベントを公開対面形式で実施できないため、オンラインでの最終選考会をデベロッパーや、株式会社 Sisilala 安藤様を始めとする業界のさまざまな方からのご協力のもと開催することができました。
多くの取り組みが変更を余儀なくされる中でも、従来のイベントでは実現できなかった Top 20 全作品のプレゼンテーション枠の確保など、オンラインだからこそ実現できることに取り組みました。動画内では、Top 3 に入賞した合同会社リビルドゲームスの「METBOY!」様からイベントに対する感想も頂戴しています。
Google Play | Indie Games Festival 2020 の詳細をまとめた動画をご覧ください。
この記事は Nick Rout による Android Developers Blog の記事 "MAD Skills Material Design Components: Wrap-Up" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Modern Android Development(最先端の Android 開発)について取り上げる連載シリーズ MAD Skills の動画と記事の 3 番目のトピックが完結しました。今回は、マテリアル デザイン コンポーネント(MDC)についてご説明しました。このライブラリは、マテリアル コンポーネントを Android ウィジェットとして提供します。これを使うと、マテリアル テーマ、ダークテーマ、モーションなど、material.io で使われているデザイン パターンを簡単に実装できます。
説明した内容については、下記にまとめた各エピソードからご確認ください。これらの動画では、MDC についての最新の記事や、既存のサンプルアプリ、Codelab を詳しく説明しています。また、MCD チームのエンジニアによる Q&Aセッションも含まれています 。
最初のエピソードは、Nick Butcher が、なぜ私たちが MDC の利用を推奨するのかなど、今回の MAD Skills シリーズ全体の概要を説明しています。その後、マテリアル テーマ、ダークテーマ、モーションについて詳しく掘り下げていきます。また、MDC を Jetpack Compose と合わせて使う方法、MDC やテーマ、スタイルのベスト プラクティスを含むようにアップデートされた Android Studio のテンプレートについてもお話ししています。
エピソード 2 では、Nick Rout がマテリアル テーマについて説明し、Android で MDC を使ってこれを実装するチュートリアルについて解説しています。主な内容は、Theme.MaterialComponents.* アプリのテーマを設定し、material.io のツールを使用して色や種類、形状の属性を選択し、最終的にそれらをテーマに追加して、ウィジェットがどのように自動的に反応して UI を適応させるかを確認します。また、テーマカラー属性を解決する、イメージに図形を適用するなど、MDC が特定のシナリオ向けに提供している便利なユーティリティ クラスについても説明します。
Theme.MaterialComponents.*
Chris Banes が、Android アプリで MDC を使ってダークテーマを実装する方法を紹介しています。説明する内容は、Force Dark を使って短時間で変換しビューを除外する方法、デザインを選んでダークテーマを手動で作成する方法、`.DayNight` MDC アプリテーマ、`.PrimarySurface` MDC ウィジェット スタイル、そしてシステム UI を扱う方法などです。
エピソード 4 では、Nick Rout がマテリアルのモーション システムについて解説しています。また、既存の「Android でマテリアル モーションを使って美しい画面遷移を構築する」Codelab の手順を詳しくフォローしています。この Codelab では、Reply サンプルアプリを使って、コンテナ変換、共有軸、フェードスルー、フェードという遷移パターンを活用してスムーズでわかりやすいユーザー エクスペリエンスを実現する方法を紹介しています。また、Fragment(Navigation コンポーネントを含む)、Activity、View を使うシナリオについて説明しています。
エピソード 5 は、Android コミュニティから Google Developer Expert (GDE) の Zarah Dominguez さんが、MDC カタログアプリをウィジェットの機能や API の例として参考にしながら紹介してくれました。そのほか、異なる画面やフローにまたがる一貫したデザイン言語を確保するために、彼女が取り組んでいるアプリに「テーマショーケース」ページを構築することが、どのように有益であるかを説明しています。
最後のまとめとして、Chet Haase が MDC エンジニアリング チームの Dan Nizri と Connie Shi と一緒に Q&A セッションを行い、Twitter や YouTube で寄せられた皆さんからの質問に回答しました。このセッションでは MDC の起源、AppCompat との関係、今までの改善点について解説したほか、テーマやリソースを整理するためのベストプラクティス、さまざまなフォントやタイポグラフィ スタイルの使用方法、シェイプ テーミングなどについてお話しました。また、私たちはお気に入りの Material コンポーネントをすべて公開し、最後に、将来的に MDCと Jetpack Compose という Androidの次世代 UI ツールキットでは、デフォルトで Material Design が組み込まれる新しいコンポーネントが登場することについて議論しました。
このシリーズでは、MDC のデモとして、次の 2 つのサンプルアプリを使いました。
これらは、もう 1 つの Material Studies のサンプルアプリである Owl とともに、GitHub リポジトリの MDC サンプルで確認できます。
Google は最新の技術情報やツールを、ウェブサイトやブログ、メール、各種動画、オンラインや対面のイベントで広くデベロッパーの皆さまに提供しています。2020 年はオンラインでの情報発信を強化し、Android 11 Android Developers Japan Blog の開設や、Android 11 Meetups をはじめ、さまざまなイベントをオンライン開催に切り替えました。以前より、サービスの改善と技術力、スキルの向上に Google の最新技術を積極的にご活用頂いている株式会社 LIFULL は、昨年から本年にかけてマテリアル デザインを使ってアプリの UI/UX を刷新しました。大規模な改修の後にも関わらず、ユーザー レビューで高い評価を得るなど、ビジネス面でも良い結果を残すことができました。
株式会社 LIFULL の取り組みをまとめた動画をご覧ください。
Posted by Tamao Imura - Developer Marketing Manager, Platforms and Ecosystems
この記事は Chris Banes による Android Developers Blog の記事 "MAD Skills — Become an Android App Bundle expert" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Modern Android Development(最先端の Android 開発)の Android App Bundle ミニシリーズが最終回のリアルタイム Q&A セッションで完結しました。私は Chet Haase、Wojtek Kaliciński、Iurii Makhno とともに、Twitter の #AskAndroid ハッシュタグやライブ ストリームのチャットから寄せられたたくさんの質問にお答えしました。
ここで少し時間を巻き戻して、最初から振り返ってみることにしましょう。
最初のエピソードでは Wojtek が、なぜデベロッパーやアプリにとって App Bundle が重要なのかを説明し、このシリーズの方向性を示しました。
このエピソードでは、Wojtek が Play Console について詳しく解説しました。Play App Signing をオプトインする方法を学習でき、Play App Signing をオプトインする際に利用できるオプションについて理解できるはずです。
この動画と合わせて、 ブログ記事 Answers to common questions about Play App Signing やアプリ署名についての Android ドキュメント、Play Console のヘルプページの Google Play アプリ署名を使用する も参照することをおすすめします。
次に、初めての Android App Bundle をビルドしてアップロードする方法を学びました。このエピソードでは、Android Studio とコマンドライン インターフェースを使ってバンドルをビルドする手順について、私がご説明しています。
このエピソードはブログ記事(英語)で読むこともできます。合わせて、App Bundle のドキュメントもご覧ください。
このエピソードでは、配信オプションについて学ぶことができます。インストール時の配信に加え、条件付き配信やオンデマンド配信など、あらゆることを解説しています。また、 GitHub のサンプルについても説明しています。
このエピソードもブログ記事(英語)で読むことができます。さらに、重要な参考資料として Play Core ガイドも準備しています。
App Bundle のテスト方法について疑問に思ったことはないでしょうか。もうその必要はありません。Wojtek が ご説明する App Bundle をローカルと Play Console でテストする方法についての動画をご覧ください。
このエピソードのコンテンツは、ブログ記事(英語)やガイド Android App Bundle のテスト で読むこともできます。
さらに、Play Console のデベロッパー ツールにガイドを掲載しており、Play Console のヘルプページでは内部アプリ共有の説明も確認できます。
また、bundletool をダウンロードしたい方は、こちらをご覧ください。
Android GDE の Angélica Oliveira さんが、Android App Bundle への切り替えを行った手順と、そのときに経験した大幅なサイズの削減について解説しています。
Twitter で質問を募集したところ、皆さんから #AskAndroid ハッシュタグ付きの返信をいただき、リアルタイム Q&A セッションの間も質問は続きました。Chet と Wojtek、Iurii、そして私がカメラの前に立ち、皆さんの質問にお答えしました。
詳しくは 2021 年の新しい Android App Bundle とターゲット API レベル要件をご覧ください。
この記事は Frank van Diggelen による Android Developers Blog の記事 "Improving urban GPS accuracy for your app" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Android では、デベロッパーの皆さんがユーザーにとって、便利なアプリをできる限り簡単に作成できるようにしたいと考えています。そのため、Fused Location Provider API(FLP)などの API では、位置情報を最大限に活用できるようにすることを目指しています。しかし、密集した都市部では、通りの反対側や誤った区画を指すなど、その位置情報の精度が低いというご指摘をこれまで多くの方からいただいておりました。
ライドシェアやナビゲーションなど、特によく利用されている位置情報アプリでは、この点が非常に重要になります。たとえば、街でユーザーがライドシェアをリクエストしても、GPS エラーのためアプリが簡単に位置を特定できない場合があります。
誤って通りの反対側を指してしまうエラーが起こる主な原因は、都市では GPS シグナルが反射しやすいためです。この大きな GPS 問題の解決に役立てるため、私たちは新しいプロジェクトを立ち上げました。そのソリューションは、3D マッピングを活用して補正を行うという方法です。これには、建物の 3D モデル、未加工の GPS 測定データ、機械学習を組み合わせる必要があるため、Google のような企業の規模でしか実現できません。
12 月の Pixel Feature Drop では、Pixel 5 と Pixel 4a5G に 3D マッピングを活用した GPS 補正が追加されます。Pixel で使われている Qualcomm® Snapdragon™ 5G Mobile Platform にフィードバックを提供するシステム API により、都市部(ビルの谷間、いわゆる「アーバン キャニオン」)での精度が大幅に向上します。
この写真から、3D マッピングを活用した補正を行わない場合、GPS の結果が不安定になって通りの反対側(または誤った区画)を指す頻度が高くなることがわかります。一方、3D マッピングを活用した補正を行うと、位置は何倍も正確になります。
都市部では GPS が構造的に誤った場所を指す点が今までの問題でした。その問題は、すべての GPS システムが衛星からの見通し線に基づいて位置を特定しているために引き起こされています。しかし大都市では、直接の信号は建物によって妨害されるため、ほぼすべての信号が障害物に反射した後に届くことになります。
GPS チップは信号が見通し線上にあることを仮定しているので、信号が余分な経路を通過してきた分だけ、計算に誤差が生じます。最も一般的な副作用は、位置が通りの反対側に表示されることですが、特に多くの高層ビルが建っている大都市では、誤った区画に表示されることもあります。
この問題は、10 年以上にわたって解決が試みられてきました。しかし、Android に 3D マッピングを活用した補正が搭載されるまでは、大規模な解決策は存在しませんでした。
Google Play サービスの 3D マッピングを活用した補正モジュールには、Google が保持している世界中の 3,850 以上の都市の 3D 建造物モデルのタイルが含まれています。現在、Google Play サービスの 3D マッピングを活用した補正は、歩行者による利用のみをサポートしています。歩きながらデバイスの GPS を使うと、Android の Activity Recognition API が今歩行していることを認識します。さらに、3,850 以上の都市のいずれかにいる場合、その都市の 3D モデルのタイルがダウンロードされ、スマートフォンにキャッシュされます。キャッシュのサイズは約 20 MB で、写真 6 枚程度の大きさです。
このモジュールでは、3D マッピングを活用した補正アルゴリズムが難問を解決します。つまり、GPS の位置が正しくない場合、どうすれば信号を妨害したり反射したりしている建物を知ることができるかという、卵が先か鶏が先かわからないような問題です。この問題は、3D マッピングを活用した補正によって解決され、FLP には一連の補正済みの位置が渡されます。システム API はこの情報を GPS チップに渡し、チップがそれ以降の GPS 精度を改善できるようにします。
12 月の Pixel Feature Drop では、Pixel 5 と Pixel 4a(5G) を対象に、3D マッピングを活用した補正のバージョン 2 をリリースします。これにより、通りの反対側を指すという現象の発生率が約 75% 減少します。Android 8 以降を使っているその他の Android スマートフォンでは、FLP にバージョン 1 が実装されており、通りの反対側を指すという現象の発生率が約 50% 減少します。2021 年初頭には、Android エコシステム全体(Android 8 以降)でバージョン 2 を利用できるようになる予定です。
Android の 3D マッピングを活用した補正は、米国の Global Positioning System(GPS)に加え、その他の Global Navigation Satellite System(GNSS)の信号にも対応しています。具体的には、GLONASS、Galileo、BeiDou、QZSS の信号です。
GPS チップ パートナーは、それぞれのテクノロジーにおけるこの作業の重要性について、次のように述べています。
「ユーザーは、モバイル スマートフォンの位置情報やナビゲーション機能の精度に依存しています。位置情報テクノロジーは、お気に入りのレストランを見つけたり、タイミングよくライドシェア サービスを利用したりする際に非常に重要ですQualcomm Technologies は、Google の 3D マッピングを活用した補正を組み込んだ最新のQualcomm® Location Suite テクノロジーによるユーザー エクスペリエンスの改善で、主導的な役割を果たしています。今回の Google との共同作業は、歩道レベルの精度の位置情報実現に向けた重要なマイルストーンです」
―― Qualcomm Technologies, Inc. プロダクト管理担当副社長、Francesco Grilli 氏
「Broadcom は、BCM47765 二周波 GNSS チップのナビゲーション エンジンに Google の 3D マッピングを活用した補正を組み込みました。二周波の L1 および L5 信号と 3D マッピングを活用した補正を組み合わせることで、アーバン キャニオンでこれまでにない精度を実現できます。L5 と Google の補正を組み合わせれば、都市部での GNSS の活用に革命を起こすことができます」
――Broadcom Inc. エンジニアリング担当シニア ディレクター、Charles Abraham 氏
「Google の 3D マッピングを活用した補正によって、スマートフォン ユーザーが都市環境で歩行しているときの個人の位置情報の精度が大きく進展しました。MediaTek Dimensity 5G ファミリーは、3D マッピングを活用した補正に対応しています。これにより、高精度デュアルバンド GNSS や業界トップレベルのデッドレコニング パフォーマンスに加えて、最高精度のグローバル位置情報を 5G スマートフォン ユーザーに提供できます」
―― MediaTek
Android 8 以降を実行しているスマートフォンでは、3,850 以上の都市で GPS をオンにして歩行しているときに、Android の 3D マッピングを活用した補正が自動的に作動します。デベロッパーがこの改善を活用する最適な方法は、FLP を使って位置情報を取得することです。GPS チップによるさらに高度な 3D マッピングを活用した補正は、現在のところ、Pixel 5 と Pixel 4a 5G で利用できます。また、今後数週間のうちに、Android エコシステム全体(Android 8 以降)に対してロールアウトされる予定です。今後、運転中などの他のモードもサポートする予定です。
Android の 3D マッピングを活用した補正は、以下を含む 3,850 以上の都市で利用できます。
Google Earth 3D モデルの拡張とともに、3D マッピングを活用した補正の範囲も広がります。
Google マップにもアップデートが行われます。これにより、一部の都市で、歩道、横断歩道、安全地帯などの歩行者向けの街区レベルの情報の精度が向上します。2021 年には、Google Maps Platform を使っているアプリにもこのアップデートが提供されます。3D マッピングを活用した補正による位置情報の精度向上と合わせて、皆さんのようなデベロッパーが、世界中で Android を使っている 20 億人の歩行者のユースケースのサポートを向上してくださることを期待しています。
私たちは 3D マッピングを活用した補正の他にも、位置情報の精度と利便性を向上する努力を懸命に続けています。Fused Location Provider API(FLP)の最新の改善項目は、以下のとおりです。
getCurrentLocation
FusedLocationProviderClient
Qualcomm および Snapdragon は、Qualcomm Incorporated の商標または登録商標です。Qualcomm Snapdragon および Qualcomm Location Suite は、Qualcomm Technologies, Inc. および/またはその子会社の製品です。
2020 年は、予想もつかない事態が続く中で、困難な状況をポジティブに変える取り組みに多くのデベロッパーの皆さまが精力を傾けてこられました。世界保健機関(WHO)と世界中のゲーム関連事業者が提唱した #PlayApartTogether (離れていっしょに遊ぼう)キャンペーンを日本でも立ち上げ推進した、株式会社ミラティブと株式会社ミクシィの取り組みもその 1 つです。
Google Play では Play ストアに特集ページを設け、賛同デベロッパーのゲームを掲載しました。詳細をまとめた動画をご覧ください。
この記事は Vesna Doknic による Google Play Developers - Medium の記事 "Churn: acting before it’s too late" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
アプリのユーザーは、3 つの基本的なグループに分けることができます。それは、エンゲージメントがない(獲得戦略によって新たに引き寄せられたグループ)、エンゲージメントが増加中(利用維持戦略によって利用が促進されたグループ)、エンゲージメントが減少中(離脱阻止戦略によってつなぎ留められているグループ)の 3 つです。これらはすべて異なる戦略が関わっているので、獲得、維持、離脱阻止をまったく別の領域として考えることは理にかなっています。しかし、離脱との闘いは軽視されることが多く、獲得の増加や、エンゲージメントの高いユーザーの維持率を上げることで、相殺できたりするものと見なされがちです。
前回の記事(英語)では、どうすればデベロッパーが効果的な維持戦略を策定できるかについて説明しました。これは、エンゲージメントの高いユーザーを維持する可能性を高めることを狙った戦略です(さらに細かく掘り下げたレポート全文をご覧ください)。しかし、戦略やアプリがどれほど素晴らしいものであっても、いくらかのユーザーは離脱してしまうものです。
ユーザーの離脱は、目先の収益以上の損失を会社にもたらします。例えば、早い段階でユーザーが離脱すれば、そのユーザーの獲得コストは完全に無駄であったということになります。また、離脱したユーザーを再定着させることは可能ですが、それには新しいユーザーを獲得するよりも費用も時間もかかる可能性が高いです。
ユーザーを再定着させるには、そもそもユーザーの離脱を引き起こした問題を直接的に克服しなければなりません。そのコストを考えると、ユーザーを再定着させるよりも、最初からユーザーが離脱しないようにあらかじめ手を打っておくほうがはるかに効果的です。
それでは、どうすれば手遅れになる前に行動できるのでしょうか。
離脱を防ぐということは、離脱が起こる前に対処するということです。すなわち、警告システムを作り、離脱の兆候を特定して早い段階で行動するのです。ユーザーは一夜にして離れるわけではありません。離脱する前には、アプリの使い方が変わり始めます。そしてそれは、計測して特定することが可能です。この危険信号を特定するには、以下の様なデータを確認し、離脱するユーザーがどのような行動をとっているのかを調べます。
Quickbooks は、詳細なモデリングによって最近離脱したユーザーの行動を分析し、高い離脱率と相関性のある行動に注目した「ユーザー リスク プロフィール」を作っています。
これは 200~300 種類のアプリ内行動をまとめたもので、機能を使用しない、休眠の日数、重要指標を達成できない、などが含まれています。詳しい方法について知りたい方は、こちらの記事(英語)をご覧ください。
Quickbooks は、このような「点検」を行うことで、即座に介入して独自の方法で望ましい行動を促し、離脱のリスクを軽減できるようにしています。
離脱を予測できるようになったら、離脱する可能性が高いユーザーを特定してアプリに呼び戻すことを試みます。そのためには、ユーザーにアプリの価値を再認識してもらわなければなりません。既に使っている機能についてのリマインダーを表示したり、近くリリースされる機能に期待してもらったりすることも効果的です。
これを行う方法の 1 つは、ユーザーがアプリを使って既に実現したことを思い出してもらうことです。Yazio は、ユーザーの進捗を目に見える形で継続的に追跡し、離脱を防ぐ方策として、頻繁にお祝いの言葉を贈っています。進行状況バーと祝福の画面を使ってユーザーのモチベーションを上げ、目標の達成を促します。
可能な限りコンテンツをパーソナライズし、ユーザーに自分が大事にされていると感じてもらえるようにするのも効果的です。Mobills は、使用率が低下したユーザーに対し、そのユーザーに合わせたメッセージを送り、ギフトを提供したり応援するようにしています。
Lifesum も、ユーザーに合わせたメッセージを送っています。ただし、ユーザーが見落としている可能性があるものを強調します。つまり、重要な機能のリマインダーを重視し、ユーザーの使用率を維持できるように、あまり知られていない機能についてお知らせしています。
アプリで定期購入を導入している場合、その更新期間には常にリスクがつきまといます。ここで最も重要なことは、適切なタイミングで適切な兆候に基づいて行動することです。そのためには、定期購入期間が終了する数週間前または数か月前、まさに離脱を示す行動が起きているときに、その行動を特定する必要があります。兆候は思ったよりも早く見つかるかもしれません。
続いて、キャンセル以外の選択肢を確実に示して、そのことをユーザーにはっきりと伝えます。ユーザーは、より手頃な価格、または広告をベースにしたオプションが存在することを知らないかもしれません。ユーザーにキャンセルの理由を与えないようにしましょう。
オファーを行うときは、価値の見せ方を工夫してみましょう。定期購入の更新をユーザーに促すのは、難しいものです。どんなメッセージがユーザーの共感を得るかを判断するために、異なるメッセージを試してみてもよいかもしれません。コストやメリット、オプションを明確に提示すれば、ユーザーは選択肢を与えられたように感じて選びやすくなる可能性があります。また、実世界の同等なものとコストを比べれば、視野を広げて価値を見直してもらえるかもしれません。Yazio は、定期購入の月間コストが 1 日 1 杯のコーヒーや他のダイエット製品よりも安いことをアピールしています。
また、常に言えることですが、パーソナライズしたメッセージを送れば、ユーザーは自分が大事にされていると感じます。Quickbooks は、定期購入のキャンセル フローの途中で、ユーザーがアプリで実現したこと(1,000 マイルを移動したなど)や、費用を払ったにもかかわらずまだ使っていなかった機能を提示しています。
上記のステップを通して、注目すべきユーザー グループとそれらのグループの障壁を表す、離脱につながるさまざまな行動パターンを発見できるかもしれません。もちろん、一部のグループでは、離脱は避けられない可能性もあります。アプリが提供するサービスの価値を誤解したユーザーや、単にそのアプリでは事足りなくなったユーザーがそういったグループに当てはまるでしょう。そういったケースもあるので、再定着に向けたさまざまな努力をしているにもかかわらず活動のレベルが低いままであるユーザー グループではなく、価値をもたらしてくれるグループに注目するようにしましょう。完全に離脱をなくすことは不可能であることを忘れないでください。
この記事が、離脱を最低限に抑える戦略の立案にお役に立つことを願っています。ここでご紹介した戦略は、「どっちつかず」のユーザーを定着させるために役立ち、獲得戦略や維持戦略とともに、アプリを継続的に成長させるために欠かせないものです。 この内容についてもっと知りたい方は、以下の関連情報をご覧ください。