2021 年 10 月 18 日に開催された、『DroidKaigi 前夜祭』に Google 関係者がパネリストとして登壇しました。


このイベントでは、2021 年に発表した Android/Google Play 関連の製品のお話や、I/O 以降に発表された製品・技術関連の最新情報についての内容を中心に Google 関係者が解説をしました。


この記事では、イベント内で解説した内容をまとめます。


Jetpack Compose 1.0 以降の最新情報


Jetpack Compose は、ネイティブ UI をビルドするための Android の最新ツールキットで、Kotlin API を使用して、少ないコードで Android の UI 開発を簡素化し、加速することができます。Google I/O では、株式会社メルカリ様のケーススタディもリリースされ、UI 開発の生産性が 56 % 向上したという実例もございます。今回のイベントでは、その Jetpack Compose の最新アップデートである、1.1.0 についてお話をさせていただきました。

 2021 年 10 月 18 日に開催された、『DroidKaigi 前夜祭』に Google 関係者がパネリストとして登壇しました。


このイベントでは、2021 年に発表した Android/Google Play 関連の製品のお話や、I/O 以降に発表された製品・技術関連の最新情報についての内容を中心に Google 関係者が解説をしました。


この記事では、イベント内で解説した内容をまとめます。


Jetpack Compose 1.0 以降の最新情報


Jetpack Compose は、ネイティブ UI をビルドするための Android の最新ツールキットで、Kotlin API を使用して、少ないコードで Android の UI 開発を簡素化し、加速することができます。Google I/O では、株式会社メルカリ様のケーススタディもリリースされ、UI 開発の生産性が 56 % 向上したという実例もございます。今回のイベントでは、その Jetpack Compose の最新アップデートである、1.1.0 についてお話をさせていただきました。


  • Jetpack Compose 1.1.0 のアルファ版がリリースされました。Compose は複数のライブラリで構成されており、今回はほとんどのライブラリが 1.1 になります。しかし、複数の Maven グループ、複数の Maven アーティファクトその全てが同一のバージョンを持つとは限りません。Compose 全体としては、必ずしもバージョンが 1 つではないということになります。しかしながら、1.0 および 1.1.0 に関してはほとんどのライブラリのバージョンが揃っています。

  • 各ライブラリのアップデート
    • compose. compiler, runtime では古いランタイムと新しいコンパイラーの組み合わせをサポートしました

    • UI の基礎になる compose.framework では、オーバースクロールのサポートを追加しました。Android 11 以前ではグロー効果が、Android 12 以降ではストレッチ効果が適用されます。

    • compose.ui では DpSize とその関連 API が追加されました。また、すりガラス効果などの RenderEffect を使えるようになりました。新しい ModifierLocal を使って、複数の modifier 間にまたがるスコープを定義できます。また、マウスを含むタッチイベントのサポートが強化され、テストで使う performTouchInput の機能が追加されました。

  • アニメーションに関するアップデートとして、コンテンツの切り替えを行う AnimatedContent API を新しくリリースしました。また、 コンテンツの出現をアニメーションする API である AnimatedVisibility が @Experimental から安定版へと移行しました。そして、AnimatedVisibility や AnimatedContent のためのオプションである scaleIn / scaleOut が追加されました。また、AnimatedImageVector という、AnimatieDrawable を Compose でも使えるという互換性のためのレイヤーが新しいライブラリとして独立する形となりました。

  • Compose Material は分かりやすい機能が新しく入りました。未読の数にバッチをつけるBadged Boxや Navigation Rail、挙動の変更点として、タッチターゲットの最小サイズがデフォルトで正しく適用されるようになりました。TextFieldColorsWithIcons で、状態に基づいてテキストフィールドの外観を変更するのが簡単になりました。


Android Developer Summit 関連セッション



Android Studio の最新情報


このセッションでは、Android IDE Android Studio (英語)  の Android Gradle Plugin API (AGP) (英語) や Test framework についてについてお話をさせていただきました。公式の強力な Android IDE Android Studio Arctic Fox (2020.3.1) ベータ版 を I/O で発表したあと、7 月に安定版をリリースしました。UI 設計期間の短縮、新しいデバイスへのアプリ拡張、デベロッパーの生産性向上を目的としており、Compose と合わせて使うことで、最新の UI をすばやくデザインすることができます。


  • Android Gradle Plugin API (AGP) (英語) に大きな変更が Arctic Fox からありました。Extending AGP の bulid のフローをカスタマイズする方法が追加されました。 AGP 7.0 以前は Task に対してのAPIが提供されており、AGPの実装依存になるため Task の並びや、他 Task の実装が変更になることに対して対応できていませんでいせんでしたが、Artic Fox 以降 では Variant と artifact に対しての API が提供されるようになったため、Task をさわることなく build をカスタマイズできるようになりました。また、finalizeDsl、beforeVariants、onVariants のコールバックが提供されており、コールバックを extend することにより Build flow をカスタマイズできるようになりました。実例は、セッション動画をご覧ください。

  • Test についても紹介いたしました。Bumblebee (英語) 以前は Android Studio 上から実行した Instrumentated tests と、Android Gradle Plugin(コマンドラインから)から実行した Instrumented tests で違う Runner を使っていたので、一方の結果がもう一方の結果と違うことが稀にありましたが、Bumblebee からは Android Studio から実行した場合でも同じ Runner を使うようになり、 Arctic Fox で Unit tests の Runner が統一されたことと含めて結果の整合性がとれるようになりました。

  • 次に大きな変更として、Unified Test Platform を紹介しました。以前は Nitrogen と呼ばれていた機能郡が Unified Test Platform と名前を変えて、Bumblebee から使用可能になりました。Unified Test Platform とは AGP に abstract layer を定義して Plugin を加える形で開発することができます。AGP とは独立して開発されるので AGP のバージョンアップとは独立して機能追加、バグフィックスなどが可能になりました。


Android Developer Summit 関連セッション



Google Play & Multi Form Factor の最新情報

このセッションでは、Google Play と Multi Form Factor についてお話をさせていただきました。

Wear OS や大画面対応から、セキュリティ ツールなどのトピックまで幅広くカバーしました。


  • Google Play Console 周りのアップデートとして、「リーチとデバイス」という機能がリリースされました。ユーザーと問題の分布(ぶんぷ)を把握することで、どのような仕様にすべきか、どの国でリリースすべきか、何をテストすべきかをより的確に判断できます。

  • また、プライバシーとセキュリティ周りのアップデートとして、セーフティ セクションについてもお話をさせていただきました。デベロッパーは、アプリの全体的な安全性を簡単に明示できるだけでなく、ユーザーがアプリをインストールする前に、プライバシーやセキュリティの慣習に関する詳しい情報を提示したり、アプリが収集するデータやその理由を説明したりできます。2021 年 10 月より、デベロッパーは Google Play Console 上で情報の申告を行い、審査を受けることができます。本件に関して、デベロッパーの皆さんが作業を行っている途中で質問が生じる可能性もありますので、お早めに準備を開始されることをお勧めします。

  • セキュリティ ツールに関しても、最新情報をお伝えいたしました。従来の SafetyNet Attestation API のアップグレードとしてご紹介しました Play Integrity API (EAP) は、ゲームのバイナリーが改変されていないか、端末そのものが改変されていないか、アプリやゲームが Google Play ストアから適切にダウンロードされたものかどうかなどが確認できる API です。デベロッパーの皆さんが日々行われているセキュリティ対策のための 1 つのツールとして、ご活用いただければと考えています。

  • Google Play Billing Library に関しての重要なトピックとして、Google Play Billing を使用する既存アプリのアップデートはすべて、2021 年 11 月 1 日までに Billing Library バージョン 3 または 4 を使用する必要があります。まだご対応いただいていない場合は、購入の承認(Acknowledgement)、再開(Restore)、アカウントの一時停止(Account hold) という 3 つが必須条件となります。

    • 購入の承認 (Acknowledgement) : Billing Libray 1 又は AIDL を採用していた方は、アプリのアプリ内の購入から 3 日以内に購入承認をしないと購入がキャンセルされてしまいますので、ご注意ください。
    • 再開 (Restore) : キャンセルされた定期購入を再開する場合、以前だとGoogle Developer APIを通じて実装する必要がありましたが、今はそれが必要なくなり、Play Storeアプリへ遷移させることでOKです。
    • アカウントの一時停止 (Account hold) : Google Play ストアの残高不足又はクレジットカードの有効期間切れなどの理由でアカウントが使えなくなった場合の処理になります。この場合、ユーザーに通知などの方法でお知らせをし、Play ストアへ遷移させる必要があります。

  • 携帯端末ではない、Chrome OS のような大きな画面を対象とした Navigation Rail (英語) や Jetpack Window Manager のトピックもカバーしました。タブレット専用の取り組みとして、Android 12 L という OS が Android Dev Summit 2021 でも発表し、Multitasking updates、Sys UI Surfaces、App Compat mode などの大画面対応のための機能も発表しました。

  • Wear OS 3.0 が実現した新しいユーザー体験として Fluid motion、 smooth transitions、​​Glanceable and user-centric、Harmonious with hardware などが追加されました。


Android Developer Summit 関連セッション



ご参加いただきました皆さん、ありがとうございました!Android Developer Summit の動画も、ぜひご視聴ください。


Written by Tamao Imura - Developer Marketing Manager, Platforms and Ecosystems

この記事は Dave Burke による Android Developers Blog の記事 " Android 12 is live in AOSP! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。


この記事は Dave Burke による Android Developers Blog の記事 " Android 12 is live in AOSP! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

2021 年 10 月 4 日 (日本時間 10 月 5 日) 、ソースを Android オープンソース プロジェクト(AOSP)にプッシュし、Android の最新バージョンを正式にリリースしました。お手元のデバイスに配信される Android 12 にご注目ください。今後数週間で Pixel に、その後今年中に Samsung Galaxy、OnePlus、Oppo、realme、TECNO、Vivo、Xiaomi の各デバイスに配信されます。

いつものことですが、Android 12 ベータ版期間中のフィードバックをありがとうございました。225,000 人以上の方が Pixel やパートナー デバイスで早期リリースをテストし、リリースの品質を改善するために 50,000 件近くの問題を報告してくれました。また、多くの記事やディスカッション、アンケート、そして直接顔を合わせて意見を述べてくださった皆さんや、リリースに間に合うようにアプリの互換性対応を行ってくださった皆さんにも感謝いたします。Android があらゆる人のための偉大なプラットフォームであるのは、皆さんのサポートや貢献があってこそです。

また、10 月 27 日から28 日に開催される今年の Android Dev Summit (英語)では、Android 12 についてさらに詳しくお伝えする予定です。各セッションの動画は、後日日本語字幕もご用意いたしますので、YouTube の「設定」から日本語字幕をオンにしてご覧ください。Android テクニカル セッションの概要など、イベントについての詳細情報も公開されています。この記事でも、後ほど改めてお知らせします。

デベロッパーのための Android 12 の新機能

ここでは、デベロッパーのための Android 12 の新機能をいくつか紹介します。Android 12 デベロッパー サイトでは、すべての新機能について詳しく説明しているので、そちらもご覧ください。

 

Android の新しい UI

Material You - Android 12 には、Material You (英語) と呼ばれる新しいデザイン言語が導入され、今まで以上にパーソナライズされた美しいアプリを構築できるようになっています。最新のマテリアル デザイン 3 アップデートのすべてをアプリに組み込むには、アルファ版の Material Design Components をお試しください。また、近日中に公開される Jetpack Compose のサポートにも注目です。

 

新しくデザインされたウィジェット - アプリ ウィジェットをより使いやすく、美しく、そして見つけやすくしました。新しく追加されたインタラクティブ コントロール、あらゆるデバイスに対応するレスポンシブ レイアウト、パーソナライズしつつも一貫性のある外観を作成するダイナミック カラーなどをお試しください。詳しくはこちらをご覧ください

 

通知 UI のアップデート - 通知のデザインも更新し、モダンで使いやすく、便利になりました。Android 12 をターゲットとしたアプリ では、カスタム通知も標準のアフォーダンスで装飾されるようになり、その他すべての通知との一貫性が向上します。詳しくはこちらをご覧ください

 

ストレッチ オーバースクロール - アプリのコンテンツをスクロールするときのスムーズさを向上させるため、Android 12 をターゲットとしたアプリでは、すべてのスクロール コンテナに新しい「ストレッチ」オーバースクロール効果が追加されています。この効果は、システムとアプリ全体に共通する自然なスクロール終了インジケーターになります。詳しくはこちらをご覧ください

 

アプリ起動時のスプラッシュ画面 - Android 12 をターゲットとしたアプリ では、すべてのアプリにスプラッシュ画面が導入されます。アプリのスプラッシュ画面はさまざまな方法でカスタマイズできるので、アプリ独自のブランディングのニーズを反映できます。詳しくはこちらをご覧ください (英語) 。 

 

パフォーマンス

システム パフォーマンスの高速化と効率化 - コア システム サービスが利用する CPU 時間を 22%、ビッグコアの利用を 15% 削減しました。また、アプリの起動時間を短縮し、アプリを速く読み込めるように I/O を最適化しました。さらに、データベース クエリでは、大きなウィンドウの CursorWindow を 49 倍近く高速化しました。

 

フォアグラウンド サービスの最適化 - ユーザー エクスペリエンスを向上させるため、Android 12 ではバックグラウンドのアプリがフォアグラウンド サービスを開始できないようになっています。それに代わる新機能として、アプリは JobScheduler で優先ジョブ (英語) を利用できます。詳しくはこちらをご覧ください

 

通知のレスポンシブ性の向上 - Android 12 では、通知トランポリンが制限されるので、通知からアプリを起動する際の時間が短縮されます。たとえば、通知トランポリン削除後の Google フォト アプリは、34% 高速に起動するようになっています。詳しくはこちらをご覧ください

 

パフォーマンス クラス - パフォーマンス クラス は一連のデバイス機能で、Android 12 デバイスで要求の厳しいユースケースや高品質なコンテンツをサポートします。アプリは、実行時にデバイスのパフォーマンス クラスを確認することで、デバイスのパフォーマンスを最大限に活用できます。詳しくはこちらをご覧ください

 

機械学習の高速化 - Android 12 では、Neural Networks API を通して ML アクセラレータを限界まで活用し、常に最大限のパフォーマンスを発揮できるようになっています。また、ML アクセラレータ ドライバは、プラットフォーム リリースとは独立して Google Play 開発者サービスでアップデートできるようになるので、互換性のあるすべてのデバイスで最新ドライバのメリットを活用できます。

 

プライバシー

プライバシー ダッシュボード - 設定アプリの新しいダッシュボードを使うと、ユーザーはアプリがマイク、カメラ、位置情報データにアクセスしたタイミングを視覚的に確認できます。詳しくはこちらをご覧ください

 

おおよその位置情報 - ユーザーは位置情報データをさらに細かくコントロールできるようになり、アプリが厳密な位置情報をリクエストした場合でも、おおよその位置情報のみを許可できるようになります。詳しくはこちらをご覧ください

 

マイクとカメラのインジケーター - アプリがデバイスのカメラやマイクを使っているタイミングを、ステータスバーのインジケーターでユーザーに知らせます。詳しくはこちらをご覧ください

 

マイクとカメラの切り替え - サポート対象のデバイスで、クイック設定の新しい切り替え機能から、アプリからのマイクやカメラに対するアクセスをすぐに簡単に無効化できるようにします。詳しくはこちらをご覧ください

 

周辺デバイス権限 - アプリで新しい権限を使うと、位置情報の権限がなくても、周辺デバイスのスキャンやペア設定を行えます。詳しくはこちらをご覧ください

 

より最適なユーザー エクスペリエンスのためのツール

リッチ コンテンツの挿入 - 新しい統合 API を使うと、UI で任意のソース(クリップボード、キーボード、ドラッグ アンド ドロップ)からリッチ コンテンツを受信できます。下位互換性を確保するため、この統合 API は AndroidX にも追加しています。詳しくはこちらをご覧ください

 

角の丸い画面のサポート - 多くの最新デバイスで、角の丸い画面が使われています。こういったデバイスで優れた UX を提供するため、新しい API を使って角に関する詳細な情報を問い合わせ、必要に応じて UI 要素を管理できます。詳しくはこちらをご覧ください


AVIF イメージのサポート
- Android 12 には、AV1 画像ファイル形式(AVIF)のプラットフォーム サポートが追加されています。AVIF は動画圧縮に由来するフレーム内符号化コンテンツを利用しており、JPEG などの古い画像形式と比較すると、同じファイルサイズで画質が大幅に向上しています。

 

互換メディア コード変換 - HEVC 形式の動画は画質と圧縮率が大幅に向上しており、すべてのアプリでこの形式のサポートが推奨されています。それができないアプリでは、互換メディア コード変換機能を使って AVC ファイルをリクエストすると、システムがコード変換を行ってくれます。詳しくはこちらをご覧ください

 

ぼかしや色フィルタなど、エフェクトの使い勝手の向上 - 新しい API では、ビューやレンダリング階層でよく使われるグラフィック エフェクトを適用しやすくなっています。RenderEffect (英語) を使うと、RenderNode (英語) やビューにぼかしや色フィルタなどを適用できます。新しい Window.setBackgroundBlurRadius() (英語)  API を使うと、ウィンドウの背景にすりガラス エフェクトをかけることもできます。また、blurBehindRadius (英語) を使うと、ウィンドウの後ろにあるすべてのコンテンツをぼかすことができます。

 

触覚フィードバックの拡張 - Android 12 では、UI イベントに対する効果的な触覚フィードバック、ゲーム向けの迫力ある楽しい効果、生産性を高めるために注意を促す触覚フィードバックを作成するツールを拡張しています。詳しくはこちらをご覧ください

 

新しいカメラ効果とセンサー機能 - アプリで新しいベンダー拡張機能 (英語) を使うと、ぼけ、HDR、ナイトモードなど、デバイス メーカーが組み込んだカスタムのカメラ効果を活用できます。新しい API では、Quad / Nona Bayer パターンを利用する超高解像度カメラセンサーをフル活用することもできます。詳しくはこちらをご覧ください

 

ネイティブ コードでのクラッシュのデバッグの改善 - Android 12 では、今までよりも実用的な診断情報が提供されるので、NDK 関連のクラッシュのデバッグが簡単になります。App Exit Reasons API (英語) を使うと、アプリから Tombstone と呼ばれる詳細なクラッシュ ダンプファイルにアクセスできます。

 

Android 12 でのゲーム - Game Mode API (英語) を使うと、プレーヤーがゲームのパフォーマンス プロファイル(長時間通勤用にバッテリー寿命を延ばす、パフォーマンス モードで最高のフレームレートを実現するなど)を選択する操作に応答できます。インストール時にバックグラウンドでゲームアセットをフェッチできるようにする Play as you download を使うと、プレーヤーをすばやくゲームプレイに導くことができます。

 

Android 12 リリースに向けたアプリの準備

Android 12 が一般公開リリースされたので、ユーザーがスムーズに Android 12 に移行できるよう、すべての Android デベロッパーの皆さんに互換性テストを終えてできる限り早くアップデートを公開することをお願いします。

アプリの互換性をテストするには、Android 12 が動作するデバイスにインストールし、アプリのフローを確認して機能や UI の問題を探します。Android 12 でのすべてのアプリが対象となる動作の変更点を確認し、影響を受ける可能性がある領域を集中的にテストしてください。特にテストしておくべき変更点は、以下のとおりです。

 

  • プライバシー ダッシュボード — [設定アプリ] でこの新しいダッシュボードを使い、アプリからのマイクや位置情報などの機密データへのアクセスを確認します。また、アクセスする理由の詳細をユーザーに提供することも検討してください。詳しくはこちらをご覧ください

  • マイクとカメラのインジケーター — Android 12 では、アプリがカメラやマイクを使っていると、ステータスバーにインジケーターが表示されます。これがアプリの UI に影響しないことを確認します。詳しくはこちらをご覧ください

  • マイクとカメラの切り替え — クイック設定の新しい切り替え機能からマイクやカメラへのアクセスを無効化してみて、アプリが変更に対して適切に対応できることを確認します。詳しくはこちらをご覧ください

  • クリップボードの読み取り通知 — アプリが予期しないタイミングでクリップボードからデータを読み取ったときのトースト通知を確認します。意図しないアクセスは削除してください。詳しくはこちらをご覧ください

  • ストレッチ オーバースクロール — スクロールするコンテンツで新しい「ストレッチ」オーバースクロール効果を試し、予想どおりに表示されることを確認します。詳しくはこちらをご覧ください

  • アプリのスプラッシュ画面 — さまざまなフローからアプリを起動し、新しいスプラッシュ画面のアニメーションをテストします。必要に応じてカスタマイズすることもできます。詳しくはこちらをご覧ください

  • keygen の変更 — いくつかの非推奨の BouncyCastle 暗号アルゴリズムが削除され、Conscrypt バージョンに置き換わります。アプリで 512 ビット鍵の AES を使っている場合は、Conscrypt がサポートする標準サイズを使う必要があります。詳しくはこちらをご覧ください


アプリのライブラリや SDK の互換性テストも忘れずに行ってください。SDK の問題を見つけた場合は、最新バージョンの SDK にアップデートするか、デベロッパーに連絡してサポートを求めます。

現在のアプリの互換性のあるバージョンを公開したら、アプリの targetSdkVersion をアップデートするプロセスを開始できます。Android 12 アプリの動作の変更点を確認し、互換性フレームワークを使って問題をすばやく検知します。

 

Android Dev Summit で Android 12 の詳細情報を学ぼう!

#AndroidDevSummit (英語) が帰ってきます。10 月 27 日から28 日(日本時間 10 月 28 日 - 29 日) に開催される、イベントでは、Android 12 を含む Android 開発の最新情報をご紹介します。今年のテーマは、Excellent apps, across devices(デバイスを超える優れたアプリ体験)です。開発ツールや API、タブレットやウェアラブルを含む数十億台のデバイス間で使用できる優れたアプリの開発や、生産性向上を支援する技術についてお話しする予定です。

30 以上の Android テクニカル セッションの概要など、イベントについての詳細情報も公開されました。セッションの情報はこちら(英語) から確認できます。どのセッションに参加するか、計画を立て始めましょう。今後数週間のうちに、皆さんの質問を #AskAndroid に共有することをお願いする予定です。寄せられた質問には、Android チームがイベントの中でライブで回答します。

 

イベントは、太平洋時間の 10 月 27 日午前 10 時(日本時間 28 日午前 2 時)に開催される 50 分の技術関連の基調講演「The Android Show」でキックオフします。ここでは、Android デベロッパー向けのあらゆる最新ニュースや最新情報を共有しますこちら (英語) のニュースレターに登録して最新情報を受け取りましょう。


Reviewed by Tamao Imura - Developer Marketing Manager, Google Play

この記事は Sameer Samat による Android Developers Blog の記事 " Evolving our business model to address developer needs" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。


この記事は Sameer Samat による Android Developers Blog の記事 " Evolving our business model to address developer needs" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

10 年以上前に Google が Android と Google Play の提供を始めた頃、私たちは自由でオープンなモバイル エコシステムが、業界を支配していた独占的で閉ざされた世界と競争できると信じ、その可能性の実現に挑戦しました。その当時は、どのようなビジネスがモバイル化されるか、どのアプリが成功するかは分かりませんでした。そのため、大多数のデベロッパーが Google Play で無料でアプリを配信できるという、シンプルなビジネスモデルを採用しました(現在は 97% のデベロッパーが無料でアプリを配信)。有料のアプリやアプリ内でデジタル商品を販売しているデベロッパー(現在は 3% のデベロッパー)には、一律のサービス手数料として 30% を適用しました。このモデルにより、モバイルアプリは、最も急成長したソフトウェア分野の一つになりました。また、Google Play のサービス手数料により、OS のライセンス料を請求することなく、Google による Android と Google Play への継続的な投資と、さらには世界中のデバイスメーカーが無料で両サービスを使用することが可能になりました。
世界中のデベロッパーの創造性と革新性は、 Android の提供を開始したときには想像もできなかった画期的な新しいアプリ体験を生み出しました。エコシステムが進化するにつれ、これらの異なるタイプのアプリをサポートするために、より幅広いビジネスモデルが登場しました。私たちはその過程で、あらゆるビジネスが成功できるよう、「単一のサービス手数料モデル」からの脱却などの重要な変更を行ってきました。そして現在、私たちは単一のサービス手数料に代わり、多様なアプリエコシステムを支援し、促進するための複数のプログラムを有しています。
その結果、サービス手数料が適用されるデベロッパーの 99% が 15% 以下の手数料の対象となります。また、Anghami、 AWA、 Bumble、 Calm、 Duolingo、 KADOKAWA、 KKBOX、 PicsArt、 そして Smule のような、さまざまな業界や地域のデベロッパーの皆さまから学び、ご意見に耳を傾けた結果、私たちは Google Play のパートナー エコシステムに対するさらなる支援、パートナーの皆さまが持続可能なビジネスを構築することを手伝い、さらには Google Play が今後もモバイル アプリ エコシステムをリードすることができるよう、追加の変更を発表いたします。

定期購入のサービス手数料を 15% に引き下げます

デジタル コンテンツの定期購入は、デベロッパーにとって急速に成長しているビジネスモデルの 1 つであると同時に、私たちは定期購入ビジネスが、顧客の獲得と維持に特有の課題を抱えていることも理解しています。私たちは、出会い、フィットネス、教育などの分野のパートナーと協力し、これらの分野のビジネスのニュアンスを理解するよう努めてきました。現在、定期購入者による支払い期間が最初の 1 年目の定期購入の場合、サービス手数料は 30% となっており、その後 15% になっています。しかしながら、定期購入ビジネスが減額された料率のメリットを受けることは、定期購入ユーザーの離脱により難しいとの声がデベロッパーの皆さまから上がっています。そこで、私たちは、デベロッパーの皆さまがメリットを受けられるよう、この仕組みをシンプルにします。


定期購入を提供しているデベロッパー特有のニーズを支援するため、2022 年 1 月 1 日より、Google Play のすべての定期購入に対し、1 日目からサービス手数料を 30% から 15% に引き下げます
この変更は、定期購入を提供しているデベロッパーにとって、最初の 1 年目のサービス手数料が半分になるということです。パートナーのデベロッパーの皆さまからも、この変更に対してポジティブなフィードバックを既に頂いています。

「Google とのパートナーシップは、私たちのビジネスにとってパワフルなものであり、世界中の女性に力を与えるという私たちの使命を推進する上で、私たちが規模を拡大し、最終的に重要な役割を果たすことを支援してくれています。Google が発表した価格変更は、製品に対するより良い投資やユーザーが自信を持ってオンラインでつながることを可能にします。」
– Whitney Wolfe Herd, Founder and CEO, Bumble Inc.

「人によって学び方が違うように、それぞれのデベロッパーにも違いがあります。私たちは、 Google がデベロッパーとプラットフォームの双方に通用するモデルを見つけるために、継続的にエコシステムとコラボレーションを行っていることをワクワクしながら見ています。この定期購入手数料の減額は、『すべての人に言語学習のチャンスを』という私たちのミッションを加速させることに役立ちます。」
- Luis von Ahn, Co-Founder and CEO of Duolingo.


進化するクロス プラットフォーム体験

アプリがモバイル端末にとって非常に重要であることは変わらない一方で、今日における素晴らしいサービスは、テレビ、自動車、時計、タブレット端末などでも提供されていなければなりません。そして、私たちは、デベロッパーがこれまで以上に、これらのプラットフォーム向けの開発に投資する必要があると認識しています。
動画、オーディオ、ブックスのデベロッパーの皆さまに 素晴らしいクロスデバイス体験を開発していただき、 Android プラットフォームの成長を促進していただくために、Google Play メディア エクスペリエンス プログラムを今年初めに発表しました。このプログラムでは、 15% を下限として減額されたサービス手数料を通じ、デベロッパーの皆さまのマルチスクリーン体験への投資を支援しています。
カテゴリーの違いにより良く対応するために、2021 年 10 月 21 日(日本時間:10 月 22 日) にメディア エクスペリエンス プログラムのサービス手数料の変更も発表しました。コンテンツ コストが売上の大半を占める E ブックスとオンデマンドの音楽ストリーミングサービスを対象に、サービス手数料を10 % を下限として 引き下げます。この新しい料率は、メディア コンテンツ業界の経済構造を認識し、Google Play をデベロッパーとアーティストやミュージシャン、作家にとってより良いものにします。詳細は、こちらをご確認ください。


日本のデベロッパーの方々からも、この変更に対してコメントを頂戴しています。

「今回の Google Play のアップデートは、我々 BOOK☆WALKER にとってはもちろんのこと、電子書籍業界全体、そして出版業界にとって、ビジネスを更に大きく成長させるために意義あるものと捉えております。長らく直面していた決済周りの様々な課題を解決するものと信じており、今後も Android のアプリを通じて、より良いユーザー体験を提供していきたいと考えています。」
株式会社KADOKAWA 執行役員 Chief Digital Officer
株式会社ブックウォーカー 代表取締役社長 橋場 一郎 氏
 
「Google Play はローンチ当初より AWA をパートナーとして扱い、成長を継続的にサポートしてくださってます。今回のアップデートは、音楽業界が直面する課題を親身に考えてくださり、今後の成長のためにプラットフォーマーとしてできることをアクションに移してくだ さった新たな一例です。今回の変更を足がかりに、AWA は今後も時代に沿った新たな音楽体験とクリエイターの創造サイクルを作るために、これまで以上により良いユーザー体験を Play にて届けていきたいと思います。」
AWA株式会社 代表取締役 CEO 冨樫 晃己 氏


Google は、デベロッパーの皆さまとの継続的な会話を通して、デベロッパーの課題や機会を理解し、持続可能なビジネスを構築するためにどのような支援ができるかを考えていきます。これは、2021 年 10 月 27 日から 28 日(日本時間:10 月 28 日から 29 日)に開催する、Android Developer Summit の中心となるテーマでもあります。Android Developer Summit では、デベロッパーの生産性を高め、より優れたアプリの開発を支援するために設計された、最新のツール、アプリケーション・プログラミング・インターフェース(API)、およびテクノロジーについて詳しく説明します。
Google Play と Google Play のサービス手数料についての詳細情報をお探しの方は、よくある質問に対しての回答を掲載している、こちらの FAQ をご覧ください。


Reviewed by Tamao Imura - Developer Marketing Manager, Google Play

この記事は Mike Yerou による Android Developers Blog の記事 " Improved Google Play Console user management: access requests, permission groups, and more " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

この記事は Mike Yerou による Android Developers Blog の記事 " Improved Google Play Console user management: access requests, permission groups, and more " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。


ユーザー管理は、あらゆる規模の企業にとって重要な業務です。難しいのは、業務を行うために必要な一連の権限を必要なチームメンバーに確実に付与する一方、不要な業務データを見せないように管理することです。

Google Play Console のユーザーと権限の管理ツールを強化し、効率的かつ確実に拡大に対応できるようにしてほしいという要望は、何年も前から寄せられていました。そこでこのたび Google Play Console を再設計することで、それを実現しました。インターフェースを整理して必要なものがすぐ見つかるようにし、さらにチームを簡単に管理できる新機能を追加しています。

管理者が簡単にチームを管理できるように、[ユーザーと権限]のページを再設計

権限の名前と説明を刷新し、ユーザーに何を許可するのか、何を許可しないのかがわかりやすくなっています。また、アカウント レベルとアプリレベルの権限を明確に区別して表示するようになっています。

新しく追加された検索、フィルタ、一括編集の機能を使うと、一部のユーザーをすばやく表示したり操作したりできます。

さらに、簡単に確認できるように、デベロッパー アカウントのユーザーリストを CSV 形式でエクスポートする機能も追加しました。

 

新しいアクセス リクエスト

通常、ユーザーの権限を設定するのは管理者です。しかし、ワークフローに権限が必要であることがわかったときに、ユーザーが権限をリクエストできれば便利だという要望もありました。そして今回、それが可能になりました。管理者はリクエストを承認する必要がありますが、ユーザーが必要な権限を厳密に指定して依頼できるようになるので、管理者の作業時間を大幅に短縮できます。

Google Play Console では、サポートされているにもかかわらず権限がなくて実行できないアクションの隣に、[アクセス リクエスト] ボタンが表示されるようになります。ユーザーは、それが必要な理由を管理者に向けて記述するだけで、権限をリクエストできます。管理者には [受信トレイ] 経由で通知され、特定のユーザーやアプリに権限を付与したり、一度だけ拒否したり、ユーザーが機能を使用できないように永久的に拒否したりできます。現在のところ、この機能はアプリの権限でのみサポートされます。

チームメンバーが特定の権限へのアクセスをリクエストすることが可能に

新しい権限グループ

ある程度の規模に達した企業では、複数の人が同じ役割(プロジェクト マネージャー、デザイナーなど)を担うことが珍しくありません。その場合、管理者が同じ一連の権限を何度も何度も割り当てなければならないこともあるでしょう。

その時間を節約できるように、権限グループを導入しました。管理者は一連の権限を持つグループを作成でき、ユーザーをそのグループに追加すると、権限が自動的に引き継がれます。グループの権限が一定期間後に失効するような設定も可能です。ユーザーを複数のグループに含めたり、グループ間で権限を重複させたりしても構いません。権限グループを活用すれば、日常業務を改善し、積極的に権限を委譲して、ユーザー管理の手間を減らせるはずです。

今回の変更によって管理者の生産性が向上し、チームが Google Play Console を最大限に活用できるようになることを期待しています。権限管理の詳細については、ヘルプセンターをご覧ください


Reviewed by Sakura Teramae - Google Play Android Developer Support 

この記事は Wayne Lu による Android Developers Blog の記事 " Answering your top questions on Android Game Development Kit " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

この記事は Wayne Lu による Android Developers Blog の記事 " Answering your top questions on Android Game Development Kit " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

2021 年 7 月に Android Game Development Kit(AGDK) (英語)  をリリースしてから、デベロッパーの皆さんよりお寄せいただいた主な質問をまとめました。その内容は、AGDK のライブラリやツールから、Android のメモリ最適化、グラフィックスの実装に関することまで、さまざまです。

 

AGDK とゲームエンジン

まず、新進気鋭のゲーム デベロッパーから寄せられた、AGDK の一連のライブラリやツールの使い方に関する質問です。セットアップに応じて、以下の事項を推奨しています。

  1. Defold (英語) 、Godot (英語) 、Unity (英語) 、Unreal (英語) などの人気ゲームエンジン (英語) をお使いのゲーム デベロッパーは、Android アプリ開発ガイドを参考にすることができます。こういったゲームエンジンを使うと、テクノロジー スタック全体ではなく、ゲームプレイの構築に集中することができます。

  2. Unreal Engine を使っており、PC や専用機などの複数のプラットフォームをターゲットにしている場合は、Android Game Development Extension(AGDE)(英語)をワークフローに追加するとよいかもしれません。

  3. 独自のゲームエンジンのカスタマイズや開発を実施するデベロッパーにも対応しています。詳しくは、C または C++ のドキュメントをご覧ください。(英語)

ご自身の環境に合致したゲームエンジンとワークフローに沿って、ゲーム内で利用する CPU、メモリ、ネットワーク、バッテリーなどの状況を詳細に調査する Android Studio Profiler、グラフィックスに特化してプロファイリングを行う Android GPU Inspector(英語)、フレームレートや読み込み時間を端末毎に最適化する Android Performance Tuner (英語) などの各種ツールを確認しましょう。

 

Game Mode API と Interventions

続いて、Android 12 での開発に関する質問も寄せられています。Android 12 でゲームを実行するにあたって、特別なことは何も必要ありません。しかし、プレイヤーがゲーム体験をカスタマイズできるように、Game Mode API と Interventions (英語) を導入していきましょう。

  1. Game Mode API (英語) の詳細を確認し、ユーザーが対応するゲームモードを選択したときに、ゲームを最適化して最高のパフォーマンスを実現したり、電池寿命を延ばす方法を習得していきましょう。

  2. Game Mode Interventions (英語) についてご確認ください。これは、デベロッパーがアップデートを行わなくなったゲームのパフォーマンスを向上させるため、端末メーカー側 (OEM) が設定するものです。たとえば、デバイスの GPU 負荷を減らすため、 WindowManager のバックバッファのサイズを変更 (英語) することなどが挙げられます。

 

Android のメモリアクセス

2 つ目は、Android と Windows のゲーム開発におけるメモリアクセスの動作の違いについての質問です。以下に、いくつかのヒントをまとめます。

  1. モバイルゲームでは、システムとメモリを共有する必要があります。デバイスによっては、利用できるメモリが少ないものもあります。そのため、サポート対象となるさまざまなデバイスで、メモリ不足の問題を確認するテストが必要になります。テストは、(クリーンなデバイスではなく)ユーザーがインストールすることが多い一般的なアプリを搭載したデバイスで行う必要があります。

  2. ゲームが割り当てることができるメモリ (英語) 容量は、物理メモリの量、ダーティページの数、zRam(圧縮スワップ用)の合計容量など、さまざまな要因によって異なります。

  3. メモリ不足の症状としては、onTrimMemory() が呼び出される、メモリのスラッシングが起きる、ローメモリ キラーによってゲームが強制終了される、などがあります。bugreport ログを使うと、ローメモリ キラーによってゲームが強制終了されたかどうかを確認できます。Android 11 以降では、ApplicationExitInfo (英語) を確認して REASON_LOW_MEMORY(英語)  によってゲームが終了したかどうかを調べることができます。
  4. メモリのスラッシング(英語) を回避します。この現象は、メモリ不足が発生しているものの、ゲームを強制終了するほどのメモリは使っていない場合に発生します。これはシステム トレースで検知できます。この問題を回避するには、合計メモリ使用量を減らす必要があります。
  5. メモリ使用量は、Android Profilerその他のツール(英語) を使って調べることができます。

 

Android でのグラフィックスの実装

3 つ目は、Android でのグラフィックスの実装に関する質問です。選択肢には、OpenGL ESVulkan グラフィックス API があります。

  1. C++ ゲームエンジンで OpenGL ES グラフィックスを構成する(英語) 方法についてご確認ください。変数の初期化、ゲームループでのレンダリング、シーンとオブジェクトのレンダリングについて説明しています。

  2. Vulkan ガイドを確認頂き、立方体の描画、シェーダーのコンパイル、検証レイヤの設定方法などのベスト プラクティスを習得します。


AGDK に関する主な質問は、Q&A 動画でも確認できます。また、Android ゲーム開発の最新リソースには、g.co/android/AGDK (英語) からアクセスできます。


Reviewed by Maru Maruyama - Developer Relations Engineer

この記事は Android Team による Android Developers Blog の記事 " Android Dev Summit returns on October 27-28, 2021! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

この記事は Android Team による Android Developers Blog の記事 " Android Dev Summit returns on October 27-28, 2021! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

Android Dev Summit が帰ってきます!数週間後となる10 月 27-28 日(日本時間 10 月 28 日 - 29 日)のイベントでは Android 開発の最新情報をご紹介します。今年のテーマは、Excellent apps, across devices(優れたアプリを、複数のデバイス間で)です。開発ツールや API、タブレットやウェアラブルを含む数十億台のデバイス間で使用できる優れたアプリの開発や、生産性向上を支援する技術についてお話しする予定です。

Android Dev Summit は、「The Android Show」からキックオフします。イベントは、10 月 27 日午前 10 時(太平洋標準時)、日本時間の 28 日午前 2 時に開始します。技術関連の基調講演では、Android 開発者向けの最新ニュースやアップデートをご紹介します。また、Android 開発の技術的な トピックに関しての 30 以上のセッションをご用意しました。さらに、Android 開発チームが結集し、皆さんからの熱意ある質問にライブで答える #AskAndroid も開催します。今年の Android Dev Summit は、世界中の Android デベロッパーとデジタルでつながる機会ですので、ぜひご参加ください。さらに詳しく知りたい方は、こちらのニュースレターに登録して最新情報をお受け取りください。


Reviewed by Tamao Imura - Developer Marketing Manager, Google Play

この記事は Peter Visontay, Bessie Jiang による Android Developers Blog の記事 " Making permissions auto-reset available to billions more devices " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。寄稿者: Inara Ramji, Rodrigo Farell, James Kelly, Henry Chin

この記事は Peter Visontay, Bessie Jiang による Android Developers Blog の記事 " Making permissions auto-reset available to billions more devices " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。寄稿者: Inara Ramji, Rodrigo Farell, James Kelly, Henry Chin

ほとんどのユーザーは、スマートフォンで多くの時間を過ごしています。仕事をする、ゲームをする、友人とつながるなど、アプリは人々にとってデジタルライフの主要な出入り口です。多くの場合、アプリが動作するためには、何らかの許可が必要になります。しかし、特定のデバイスに何十個ものアプリが存在することを考えれば、ユーザーが以前に何を許可したかを覚えておくのは至難の業です。長期間使うことがなかったアプリであればなおさらです。

Android 11 では、アプリの権限を自動リセットする機能を導入しました。この機能は、アプリが数か月にわたって使われなかった場合にランタイム権限を自動的にリセットするので、ユーザーのプライバシー保護に役立ちます。ランタイム権限とは、アプリが許可をリクエストした際に、プロンプトがユーザーに表示されるものです。2021 年 12 月より、この機能を数十億台のデバイスに展開します。この機能は、Google Play 開発者サービス (英語) を搭載し、かつ Android 6.0(API レベル 23)以降を実行しているデバイスで自動的に有効化されます。

この機能は、デフォルトで Android 11(API レベル 30)以降をターゲットとするアプリで有効になりますが、API レベル 23 から 29 をターゲットとするアプリでは、ユーザーが手動で許可の自動リセットを有効化できます。

では、デベロッパーの皆さまにはどのような影響があるのか説明します。

例外となるケース

一部のアプリや権限は、自動的にリセットの対象外となります。たとえば、企業が利用中のデバイス管理者のアプリや、エンタープライズ ポリシーで固定された権限などです。

 

自動リセットを無効にするようにユーザーにリクエストする

必要に応じて、デベロッパーはユーザーにリクエストを行い、システムがアプリの権限をリセットしないようにすることができます。これは、主にバックグラウンドで動作し、インタラクションを必要としないアプリで便利です。主なユースケースは、こちらに記載されています。

 

現在の動作と新しい動作の比較

現在の動作

新しい動作

Android 11(API レベル 30)以降のデバイスで、権限が自動的にリセットされます。

以下のデバイスで、権限が自動的にリセットされます。

  • Google Play 開発者サービスを搭載し、Android 6.0(API レベル 23)から Android 10(API レベル 29)までのバージョン(両端値を含む)を実行しているデバイス

  • Android 11(API レベル 30)以降を実行しているすべてのデバイス


Android 11 以降をターゲットとするアプリで、デフォルトで権限がリセットされます。Android 6.0(API レベル 23)以降をターゲットとするアプリでは、ユーザーが手動で自動リセットを有効化できます。

現在の動作からの変更はありません。

アプリは、ユーザーに自動リセットの無効化をリクエストできます。

現在の動作からの変更はありません。


必要となるコード変更

API 30 以上をターゲットとするアプリが、権限の自動リセットの無効化をユーザーにリクエストする場合、デベロッパーはいくつかの簡単なコード変更を行う必要があります。アプリで自動リセットの無効化を行わない場合、コード変更は必要ありません。
注: 権限の自動リセットはデフォルトで targetSDK が API 30 以降のアプリのみに適用されるので、この API もこれらのアプリのみが対象となります。アプリの targetSDK が API 29 以下の場合、変更の必要はありません。
次の表に、新しいクロスプラットフォーム API の概要を記載します(Android 11 で公開された API との比較)。

アクション

Android 11 API

(Android 11 以降のデバイスでのみ動作)

新しいクロスプラットフォーム API

(Android 11 以降のデバイスを含む Android 6.0 以降のデバイスで動作)

デバイスで権限の自動リセットが有効化されているかどうかのチェック

Build.VERSION.SDK_INT >= Build.VERSION_CODES.R を確認

androidx.core.content.PackageManagerCompat.getUnusedAppRestrictionsStatus() を呼び出す

アプリで自動リセットが無効化されているかどうかのチェック

PackageManager.

isAutoRevokeWhitelisted() を呼び出す

androidx.core.content.

PackageManagerCompat.

getUnusedAppRestrictionsStatus() を呼び出す

アプリで自動リセットの無効化をユーザーにリクエスト

次のアクションのインテントを送信:

Intent.ACTION_AUTO_REVOKE_PERMISSIONS

次で作成したインテントを送信: androidx.core.content.

IntentCompat.

createManageUnusedAppRestrictionsIntent()



このクロスプラットフォーム API は Jetpack Core ライブラリの一部で、Jetpack Core v1.7.0 で利用できるようになります。現在、この API はベータ版です。
ユーザーに自動リセットを無効化してもらう必要があるアプリのサンプル ロジックは、以下のとおりです。
val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener(
  { onResult(future.get()) },
   ContextCompat.getMainExecutor(context)
)
 
fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Status could not be fetched. Check logs for details.
    ERROR -> { }
 
    // Restrictions do not apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }
    // Restrictions have been disabled by the user for your app.
    DISABLED -> { }
 
    // If the user doesn't start your app for months, its permissions 
    // will be revoked and/or it will be hibernated. 
    // See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> 
      handleRestrictions(appRestrictionsStatus)
  }
}
 
fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to 
  // the user explaining why permission auto-reset and Hibernation should be 
  // disabled. Tell them that they will now be redirected to a page where 
  // they can disable these features.
 
  Intent intent = IntentCompat.createManageUnusedAppRestrictionsIntent
    (context, packageName)
 
  // Must use startActivityForResult(), not startActivity(), even if 
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}
 
上のロジックは、Android 6.0 から Android 10、および Android 11 以降のデバイスで動作します。この新しい API を使うだけで十分です。つまり、Android 11 の自動リセット API を呼び出す必要はなくなります。
 

Android 12 のアプリの休止状態との互換性

新しい API は、Android 12(API レベル 31)で導入されたアプリの休止状態とも互換性があります。休止状態は、未使用アプリに適用される新たな制限です。この機能は、Android 12 より前のバージョンの OS では利用できません。
権限の自動リセットとアプリの休止状態の両方がアプリに適用されている場合、getUnusedAppRestrictionsStatus() API は、API_31 を返します。
 

リリース タイムライン

  • 2021 年 9 月 15 日 - この時点で、クロス プラットフォームの自動リセット API はベータ版です(Jetpack Core 1.7.0 ベータ版ライブラリ)。そのため、デベロッパーはすぐにこの API を使い始めることができます。この API は、権限の自動リセットをサポートしていないデバイスでも安全に使うことができます(そのようなデバイスでは、API は FEATURE_NOT_AVAILABLE を返します)。

  • 2021 年 10 月 - クロス プラットフォームの自動リセット API が安定版 API になります(Jetpack Core 1.7.0)。

  • 2021 年 12 月 - Google Play 開発者サービスを搭載し、Android 6.0 から Android 10 までのバージョンを実行しているデバイスを対象に、権限の自動リセット機能が徐々にロールアウトされ始めます。ユーザーは、これらのデバイスの自動リセット設定ページで、特定のアプリの自動リセットを有効化または無効化できるようになります。デバイスで機能がリリースされた数週間後には、未使用アプリの許可が自動的にリセットされるようになります。

  • 2022 年第 1 四半期 - 権限の自動リセット機能が、Android 6.0 から Android 10 までのバージョンを実行しているすべてのデバイスに導入されます。

Reviewed by Tamao Imura - Developer Marketing Manager, Google Play

 この記事は Manuel Vivo による Android Developers - Medium の記事 " Introduction to Hilt in the MAD Skills series " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

MAD Skills シリーズで、Hilt を紹介

 この記事は Manuel Vivo による Android Developers - Medium の記事 " Introduction to Hilt in the MAD Skills series " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

MAD Skills シリーズで、Hilt を紹介

MAD Skills 記事シリーズの Hilt についての記事です。この記事では、依存関係インジェクション(DI)が皆さんのアプリや Hilt にとって重要である理由について説明します。Hilt は、Android で DI を行うための Jetpack の推奨ソリューションです。

動画で視聴したい方は、こちらをご覧ください。


Android アプリで依存関係インジェクションの原理に従うことで、優れたアプリ アーキテクチャの土台を築くことができます。その結果、コードの再利用性が高まり、リファクタリングやテストが簡単になります。DI のメリットの詳細は、こちらをご覧ください。

プロジェクトでクラスのインスタンスを作成する場合、そのクラスが必要とする依存関係や推移的依存関係を満たしていくことで、依存関係グラフを手動で実現できます。

しかし、毎回これを手動で行うと、ボイラープレート コードが必要になり、エラーも起こりやすくなる可能性があります。たとえば、オープンソースの Google I/O アプリ iosched で利用している ViewModel をご覧ください。依存関係と推移的依存関係を含めると、FeedViewModel を作成するために必要なコードがどのくらいの量になるか想像できますか?

class FeedViewModel(

    private val loadCurrentMomentUseCase: LoadCurrentMomentUseCase,

    loadAnnouncementsUseCase: LoadAnnouncementsUseCase,

    private val loadStarredAndReservedSessionsUseCase: LoadStarredAndReservedSessionsUseCase,

    getTimeZoneUseCase: GetTimeZoneUseCase,

    getConferenceStateUseCase: GetConferenceStateUseCase,

    private val timeProvider: TimeProvider,

    private val analyticsHelper: AnalyticsHelper,

    private val signInViewModelDelegate: SignInViewModelDelegate,

    themedActivityDelegate: ThemedActivityDelegate,

    private val snackbarMessageManager: SnackbarMessageManager

) : ViewModel(),

    FeedEventListener,

    ThemedActivityDelegate by themedActivityDelegate,

    SignInViewModelDelegate by signInViewModelDelegate {

    /* ... */

}

これは難解で繰り返しが多いので、容易に間違った依存関係を取得してしまうこともあると思います。依存関係インジェクション ライブラリを使えば、依存関係を手動で提供することなく、DI のメリットを活用できます。必要なコードはライブラリがすべて生成してくれます。その際に活躍するのが Hilt です。

 

Hilt

Hilt は Google が開発した依存関係インジェクション ライブラリです。Hilt を使えば手動で書かなければならないボイラープレートをすべて生成してくれるので、アプリで DI のベスト プラクティスを最大限に活用できます。

Hilt はアノテーションを使ってコンパイル時にコードを生成するので、実行はとても高速です。その際に利用するのが、JVM の DI ライブラリである Dagger です。Hilt は、Dagger をベースに作られています。

Hilt は Android アプリの Jetpack 推奨 DI ソリューションであり、ツールや他の Jetpack ライブラリのサポートも含まれています。

 

クイック スタート

Hilt を使うアプリには、@HiltAndroidApp アノテーションを付けた Application クラスを含める必要があります。このアノテーションにより、コンパイル時に Hilt のコード生成が実行されます。また、Hilt がアクティビティに依存関係を注入するには、そのアクティビティに @AndroidEntryPoint アノテーションを付けておく必要があります。

@HiltAndroidApp

class MusicApp : Application()

 

@AndroidEntryPoint

class PlayActivity : AppCompatActivity() { /* ... */ }

 

依存関係を注入するには、Hilt から注入したい変数に @Inject アノテーションを付けます。Hilt が注入したすべての変数は、super.onCreate が呼び出されたときに利用できるようになります。

@AndroidEntryPoint

class PlayActivity : AppCompatActivity() {

 

  @Inject lateinit var player: MusicPlayer

 

  override fun onCreate(savedInstanceState: Bundle) {

    super.onCreate(bundle)

    player.play("YHLQMDLG")

  }

}

この例では、PlayActivityMusicPlayer を注入しています。しかし、Hilt は MusicPlayer 型のインスタンスを提供する方法をどのようにして認識しているのでしょうか。実は、この段階ではまだ認識していません。 Hilt にその方法を伝えるためにアノテーションを使います。

クラスのコンストラクタに @Inject アノテーションを付けることで、Hilt にそのクラスのインスタンスの作成方法を伝えることができます。

class MusicPlayer @Inject constructor() {

  fun play(id: String) { ... }

}

 

アクティビティへの依存関係の注入に必要なのは、これだけです。とても簡単でしたね。最初の例は簡単で、MusicPlayer は他の型に依存していません。しかし、他の依存関係がパラメータとして渡されると、Hilt はそれを管理し、MusicPlayer のインスタンスを提供する際にその依存関係を満たさなければなりません。

実は、ここで示した例はとても簡単で、単純すぎるものです。しかし、これを手動で行う場合、どうするかを考えてみてください。

 

手動による方法

手動で DI を行う場合、必要な型を提供し、提供するインスタンスのライフサイクルを管理する 依存関係コンテナ クラスを作ることが考えられます。つまり、まさに Hilt が内部で行っていることです。

アクティビティに @AndroidEntryPoint アノテーションを付けると、PlayActivity と関連付けられた依存関係コンテナが自動的に作成され、管理されます。手動で行うこの実装を PlayActivityContainer と呼ぶことにしましょう。MusicPlayer@Inject アノテーションを付けることで、MusicPlayer 型のインスタンスの提供方法をコンテナに伝えます。

// PlayActivity annotated with @AndroidEntryPoint

class PlayActivityContainer {

 

  // MusicPlayer annotated with @Inject

  fun provideMusicPlayer() = MusicPlayer()

 

}

 

そしてアクティビティでは、コンテナのインスタンスを作成し、それを使ってアクティビティの依存関係を設定します。これも Hilt ではアクティビティに @AndroidEntryPoint アノテーションを付けることで処理してくれます。

class PlayActivity : AppCompatActivity() {

 

  private lateinit var player: MusicPlayer

 

  // Created by Hilt when annotating the activity with @AndroidEntryPoint

  private lateinit var container: PlayActivityContainer

 

 

  override fun onCreate(savedInstanceState: Bundle) {

 

    // @AndroidEntryPoint also creates and populates fields for you

    container = PlayActivityContainer()

    player = container.provideMusicPlayer()

 

    super.onCreate(bundle)

    player.play("YHLQMDLG")

  }

}

 

アノテーションのまとめ

ここまで説明してきたのは、クラスのコンストラクタに @Inject アノテーションを付けると、そのクラスのインスタンスの提供方法を Hilt に伝えられることです。また、@AndroidEntryPoint が付いたクラスの変数にこのアノテーションを付けると、Hilt はその型のインスタンスをそのクラスに注入します。

@AndroidEntryPoint は、アクティビティだけでなく、ほとんどの Android フレームワーク クラスに追加できます。このアノテーションは、そのクラスの依存関係コンテナのインスタンスを作成し、@Inject アノテーションが付いたすべての変数を設定します。

Application クラスに付けられた @HiltAndroidApp アノテーションは、Hilt のコード生成をトリガーにするだけでなく、Application クラスに関連付けられた依存関係コンテナも作成します。

 

Hilt モジュール

Hilt の基本について理解できたので、もう少し複雑な例を見てみましょう。次の例では、MusicPlayer のコンストラクタが依存関係 MusicDatabase を受け取ります。

class MusicPlayer @Inject constructor(

  private val db: MusicDatabase

) {

  fun play(id: String) { ... }

}

 

ここでは、MusicDatabase のインスタンスを提供する方法を Hilt に伝えなければなりません。型がインターフェースである場合や、例えばライブラリから提供されているために自分がクラスを所有していない場合は、コンストラクタに @Inject アノテーションを付けることはできません。

アプリで、永続化ライブラリとして Room を使っているとしましょう。再度、PlayActivityContainer を手動で実装する場合について考えてみます。MusicDatabase を提供するとき、Room を使うと MusicDatabase は抽象クラスになります。そのため、依存関係を提供するコードを実行します。次に、MusicPlayer のインスタンスを提供するときに、MusicDatabase の依存関係を提供する(または満たす)メソッドを呼び出す必要があります。

class PlayActivityContainer(val context: Context) {

 

  fun provideMusicDatabase(): MusicDatabase {

    return Room.databaseBuilder(

              context, MusicDatabase::class.java, "music.db"

           ).build()

  }

 

  fun provideMusicPlayer() = MusicPlayer(

    provideMusicDatabase()

  )

}

Hilt では、推移的依存関係について心配する必要はありません。Hlit はすべての推移的依存関係を自動的に取得しますが、MusicDatabase 型のインスタンスの提供方法を伝えておかなければなりません。これを行うために、Hilt のモジュールを使います。

Hilt のモジュールとは、@Module アノテーションが付いたクラスです。このクラスでは、ある型のインスタンスの提供方法を Hilt に伝える関数を作成できます。Hilt が認識するこの情報は、Hilt の専門用語で バインディング とも呼ばれます。

@Module

@InstallIn(SingletonComponent::class)

object DataModule {

 

  @Provides

  fun provideMusicDB(@ApplicationContext context: Context): MusicDatabase {

    return Room.databaseBuilder(

      context, MusicDatabase::class.java, "music.db"

    ).build()

  }

}

@Provides アノテーションが付いた関数で、MusicDatabase 型のインスタンスの提供方法を Hilt に伝えています。関数本体には、Hilt が実行するコードのブロックが含まれており、先ほどの手動実装のコードとまったく同じものです。

戻り値の型が MusicDatabase となっているので、Hilt はこの関数が提供する型を認識できます。また、関数のパラメータから、対応する型の依存関係も認識できます。この例では、既に Hilt が利用できる ApplicationContext がパラメータになっています。このコードから、Hilt は MusicDatabase 型のインスタンスの提供方法を認識します。別の表現を使うなら、MusicDatabase の バインディング を取得したことになります。

Hilt のモジュールには、@InstallIn アノテーションも付いています。これは、この情報がどの依存関係コンテナやコンポーネントで利用できるかを示します。では、コンポーネントとは何でしょうか。この点について詳しく説明しましょう。

 

Hilt のコンポーネント

Hilt が生成する コンポーネント クラスは、先ほど手動でプログラミングしたコンテナのように、型のインスタンスを提供する役割を担います。Hilt はコンパイル時にアプリケーションの依存関係グラフをたどり、すべての推移的依存関係の型を提供するコードを生成します。

Hilt が生成する コンポーネント クラスは、型のインスタンスを提供する役割を担う

Hilt は、ほとんどの Android フレームワーク クラスに対して、コンポーネント、つまり依存関係コンテナを生成します。各コンポーネントの情報(バインディング)は、コンポーネント階層を伝播します。

Hilt のコンポーネント階層

MusicDatabase バインディングが Application クラスに対応する SingletonComponent で利用できる場合、その他のコンポーネントでも利用できます。

これらのコンポーネントは、コンパイル時に Hilt によって自動生成されます。コンポーネントが作成、管理され、対応する Android フレームワーク クラスに関連付けられるのは、これらのクラスに @AndroidEntryPoint アノテーションを付けたときです。

モジュールの @InstallIn アノテーションは、そういったバインディングが利用できる場所や、利用できる他のバインディングを管理するうえで便利です。

 

スコープ

再び、手動で作成した PlayActivityContainer コードについて考えてみます。気づいた方もいらっしゃるかもしれませんが、MusicDatabase の依存関係が必要になるたびに、別のインスタンスが作成されています。

class PlayActivityContainer(val context: Context) {

 

  fun provideMusicDatabase(): MusicDatabase {

    return Room.databaseBuilder(

              context, MusicDatabase::class.java, "music.db"

           ).build()

  }

 

  fun provideMusicPlayer() = MusicPlayer(

    provideMusicDatabase()

  )

}

アプリ全体で MusicDatabase の同じインスタンスを再利用したい場合もあるので、この動作は理想的ではありません。そこで、関数を使うのではなく、変数に格納すれば同じインスタンスを共有できます。

class PlayActivityContainer {

 

  val musicDatabase: MusicDatabase =

    Room.databaseBuilder(

      context, MusicDatabase::class.java, "music.db"

    ).build()

 

  fun provideMusicPlayer() = MusicPlayer(musicDatabase)

}

つまり、MusicDatabase 型のスコープがこのコンテナに適用されるようにすることで、依存関係として常に同じインスタンスが提供されるようにしています。これを Hilt で行うには、どうすればよいでしょうか。もうおわかりと思いますが、ここでも別のアノテーションを使います。

@Provides メソッドに @Singleton アノテーションを付けると、そのコンポーネントでは常にこの型の同じインスタンスを共有するように Hilt に伝えることができます。

@Module

@InstallIn(SingletonComponent::class)

object DataModule {

 

  @Singleton

  @Provides

  fun provideMusicDB(@ApplicationContext context: Context): MusicDatabase {

    return Room.databaseBuilder(

      context, MusicDatabase::class.java, "music.db"

    ).build()

  }

}

@Singleton はスコープ アノテーションです。それぞれの Hilt コンポーネントには、1 つのスコープ アノテーションが対応付けられています。

それぞれの Hilt コンポーネントのスコープ アノテーション

ある型のスコープを ActivityComponent にしたい場合、ActivityScoped アノテーションを使います。スコープ アノテーションはモジュールで利用できますが、コンストラクタに @Inject アノテーションが付いているクラスでも利用できます。

 

バインディング

バインディングには次の 2 つのタイプがあります。

  • MusicPlayer のように、スコープ アノテーションが付いていないバインディングを、スコープなしバインディングと呼びます。コンポーネントがモジュールに含まれていない場合、あらゆるコンポーネントでこのバインディングを利用できます。

  • MusicDatabase のように、スコープ アノテーションが付いたスコープ付きバインディングや、モジュールに含まれるスコープなしバインディングは、対応するコンポーネントと、コンポーネント階層の下位にあたるコンポーネントで利用できます。

Jetpack 拡張機能

Hilt は、ViewModel、Navigation、Compose、WorkManager といった人気のある Jetpack ライブラリと統合されています。

ViewModel 以外と統合する場合は、別のライブラリをプロジェクトに追加する必要があります。詳細は、ドキュメントをご覧ください。このブログ投稿の冒頭で紹介した ioschedFeedViewModel コードを覚えているでしょうか。Hilt を使うと、どのようになるか見てみましょう。

@HiltViewModel

class FeedViewModel @Inject constructor(

    private val loadCurrentMomentUseCase: LoadCurrentMomentUseCase,

    loadAnnouncementsUseCase: LoadAnnouncementsUseCase,

    private val loadStarredAndReservedSessionsUseCase: LoadStarredAndReservedSessionsUseCase,

    getTimeZoneUseCase: GetTimeZoneUseCase,

    getConferenceStateUseCase: GetConferenceStateUseCase,

    private val timeProvider: TimeProvider,

    private val analyticsHelper: AnalyticsHelper,

    private val signInViewModelDelegate: SignInViewModelDelegate,

    themedActivityDelegate: ThemedActivityDelegate,

    private val snackbarMessageManager: SnackbarMessageManager

) : ViewModel(),

    FeedEventListener,

    ThemedActivityDelegate by themedActivityDelegate,

    SignInViewModelDelegate by signInViewModelDelegate {

    /* ... */

}

この ViewModel のインスタンスを提供する方法を Hilt に伝えるために、コンストラクタに @Inject アノテーションが付いています。その点を除けば、クラスに @HiltViewModel アノテーションを付けるだけです。

これでだけです!ViewModel のプロバイダを手動で作成する必要はありません。Hilt がそれを行ってくれます。

 

さらに詳しく

Hilt は、よく使われている別の依存関係インジェクション ライブラリ Dagger がベースになっています。今後のエピソードには、Dagger が頻繁に登場する予定です。現在 Dagger をご利用の場合、Dagger と Hilt は連携して動作できます。移行 API の詳細は、ガイド(英語)をご覧ください。

Hilt についてさらに詳しく知りたい方は、特によく使われるアノテーションやその効果、使用方法を説明したクイック リファレンス(英語)をご覧ください。Hilt のドキュメントのほかに、ハンズオン形式で学習できる Codelab も公開しています。

 

今回のエピソードは以上ですが、この話はこれで終わりではありません。MAD Skills シリーズはさらに続くので、Android Developers の Medium 記事 (英語) をフォローして、投稿されたときに確認できるようにしておきましょう。


Reviewed by Tamao Imura - Developer Marketing Manager, Google Play