この記事は Chris Arriola による Android Developers - Medium の記事 " Composable Functions " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
前回の MAD Skills の Compose の基本に関する記事では、UI を Kotlin で関数として記述するという Compose の考え方について説明しました。もう XML は必要ありません。今回の記事では、この関数をさらに掘り下げ、それを使ってどのように UI を作るのか説明します。
リマインダーですが、10 月 13 日のライブ Q&A セッションで、Compose の基本についての質問にお答えします。質問はこの記事または YouTube にコメントを残すか、#MADCompose ハッシュタグを使って Twitter に投稿してください。( ※ライブ Q&A セッションは終了しました。録画はこちらからご確認いただけます。日本語字幕は、YouTube の自動字幕機能から日本語を選択してください。 )
この関数の動作の仕組みを理解するため、選択式の質問が 1 つある画面の作り方について考えてみます。これは、Compose サンプルに含まれている Jetsurvey の画面です。
この記事の動画版 (英語) はこちらからご覧いただけます。
* 日本語字幕は、YouTube の自動字幕機能から日本語を選択してください
Compose では、このアンケートの回答の 1 つの選択肢は、Image、Text、RadioButton を含む Row 関数として記述できます。
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0@Composablefun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) }}
// Copyright 2022 Google LLC.
// SPDX-License-Identifier: Apache-2.0
@Composable
fun SurveyAnswer(answer: Answer) {
Row {
Image(answer.image)
Text(answer.text)
RadioButton(false, onClick = { /* … */ })
}
Compose で UI コンポーネントを作る場合、関数に @Composable アノテーションをつけます。このアノテーションは、対象の関数がデータを UI に変換する(つまり、選択肢を UI にする)ものであることを Compose コンパイラに伝えます。¹
このアノテーションをつけた関数は、コンポーズ可能な関数、またはコンポーザブルと呼ばれます。Compose では、この関数が UI の構成要素になります。このアノテーションは簡単にすばやく追加できるので、UI を再利用可能な要素のライブラリとして整理しやすくなります。
たとえば、回答候補として提示する一連の選択肢を実装するために、選択肢のリストを受け取る SingleChoiceQuestion という新しい関数を定義し、そこで先ほど定義した SurveyAnswer 関数を呼び出すことができます。
SingleChoiceQuestion
SurveyAnswer
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun SingleChoiceQuestion(answers: List<Answer>) { Column { answers.forEach { answer -> SurveyAnswer(answer = answer) } }}
fun SingleChoiceQuestion(answers: List<Answer>) {
Column {
answers.forEach { answer ->
SurveyAnswer(answer = answer)
SingleChoiceQuestion はパラメータを受け取れるので、それを使ってアプリのロジックを指定できます。この場合は、回答候補のリストを受け取って、そこに含まれる選択肢を UI に表示します。このコンポーザブルは何も返さずに(つまり、`Unit` を返します)UI を生成している点に注意してください。具体的に言えば、生成されるのは Column レイアウト コンポーザブルです。これは Compose ツールキットの一部で、項目を垂直に並べます。この Column の中に、それぞれの選択肢を表す SurveyAnswer コンポーザブルが生成されます。
Column
コンポーザブルは不変です。また、いずれかの選択肢への参照を保持するというようなこと、つまり、コンポーザブルへの参照を保持して、後からその内容を更新することはできません。必要なすべての情報は、コンポーザブルを呼び出すときにパラメータとして渡さなければなりません。
関数は Kotlin で書かれるので、Kotlin の構文と制御フローをフル活用して UI を生成できます。ここでは、forEach で各選択肢の反復処理をし、SurveyAnswer を呼び出して表示しています。条件に基づいて何かを表示したいなら、if 文を使うだけで簡単に実現できます。View.visibility = View.GONE や View.INVISIBLE はもう必要ありません。Compose のような宣言的 UI フレームワークでは、与えられる入力によって UI の表示を変えたい場合、それぞれの入力値に対して UI をどのように表示するかをコンポーザブルに記述しなければなりません。これを実現するには、次のスニペットのような条件文を使います。
forEach
View.visibility = View.GONE
View.INVISIBLE
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun SingleChoiceQuestion(answers: List<Answer>) { Column { if (answers.isEmpty()) { Text("There are no answers to choose from!") } else { answers.forEach { answer -> SurveyAnswer(answer = answer) } } }}
if (answers.isEmpty()) {
Text("There are no answers to choose from!")
} else {
コンポーザブルは、高速かつ副作用がないものでなくてはなりません。同じ引数で複数回呼ばれた場合、同じ動作になる必要があり、プロパティやグローバル変数を変更してはいけません。この特性を持つ関数を、 「べき等」と呼びます。新しい値で関数を再呼び出しするときに、UI が正しく生成されるために、この特性はすべてのコンポーザブルに必須となります
関数に渡すパラメータで UI のすべてが決まる点に注意してください。状態を UI に変換するというのは、このことを表しています。UI が常に同期されることは、関数のロジックによって保証されます。選択肢のリストが変更されれば、関数が再実行されて新しい選択肢のリストから新しい UI が生成され、必要に応じて UI が再描画されます。
状態が変化したときに UI を再生成するこの処理を、再コンポーズと呼びます。コンポーザブルは不変なので、再コンポーズは新しい状態で UI を更新する唯一の仕組みです。
再コンポーズは、コンポーザブルが別の関数パラメータで再度呼び出されたときに発生します。再コンポーズが発生するのは、関数が依存する状態が変わるからです。
たとえば、SurveyAnswer コンポーザブルが isSelected パラメータを受け取るとしましょう。このパラメータは、選択肢が選択されているかどうかを表します。最初は、どの選択肢も選択されていません。
isSelected
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun SingleChoiceQuestion(answers: List<Answer>) { answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = false, ) }}
SurveyAnswer(
answer = answer,
isSelected = false,
)
ビューの世界では、ビューがそれぞれの状態を保持しているので、いずれかの選択肢の UI 要素をタップすると、その表示が切り替わります。しかし、Compose の世界では、すべての SurveyAnswer コンポーザブルで false が指定されているので、ユーザーが操作したとしても、すべての選択肢が未選択のままになります。ユーザーの操作に視覚的に応答できるようにするには、コンポーザブルを再コンポーズして新しい状態で UI を再生成できるようにしなければなりません。
Compose
そのために、選択されている選択肢を保持する新しい変数を追加します。さらに、この変数は MutableState (英語) でなければなりません。この型は、Compose ランタイムに組み込まれている監視可能な型です。状態が変化すると、それを読み取るすべてのコンポーザブルが自動的に再コンポーズされるようにスケジュールされます。新しい MutableState は、mutableStateOf (英語) メソッドを使って次のように作成します。
MutableState
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun SingleChoiceQuestion(answers: List<Answer>) { // Initialize selectedAnswer to null since no answer will be selected at first var selectedAnswer: MutableState<Answer?> = mutableStateOf(null) answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer.value == answer), ) }}
// Initialize selectedAnswer to null since no answer will be selected at first
var selectedAnswer: MutableState<Answer?> =
mutableStateOf(null)
isSelected = (selectedAnswer.value == answer),
上のスニペットでは、現在選択されている選択肢である selectedAnswer と比較することで、isSelected の値を更新しています。selectedAnswer は MutableState 型なので、選択されている選択肢は value プロパティを使って取得します。この値が変化すると、Compose は自動的に SurveyAnswer を再実行し、それによって選択されている選択がハイライト表示されます。
selectedAnswer
ただし、上のスニペットは正しく動作しません。selectedAnswer 値は、再コンポーズが発生しても保持されなければなりません。そうでないと、SingleChoiceQuestion が再実行されたときにこの値が上書きされてしまいます。これを解決するため、忘れないように mutableStateOf の中で呼び起こす必要があります。これにより、コンポーザブルが再コンポーズされても、値がリセットされずに保持されることが保証されます。構成の変更が発生した場合でも値を保持する別の方法として、rememberSaveable を使うこともできます。
mutableStateOf
rememberSaveable
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: MutableState<Answer?> = rememberSaveable { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer.value == answer), ) }}
rememberSaveable { mutableStateOf(null) }
上のコード スニペットは、さらに selectedAnswer 変数で Kotlin の委譲プロパティ構文を使うと、改善できます。こうすることで、型を MutableState<Answer?> から Answer? 値に変えることができます。この構文は、ベースとなる状態の値を直接扱うことができ、MutableState オブジェクトの value プロパティを呼び出す必要がなくなるかなり優れたものです。
MutableState<Answer?>
この新しく追加した状態があれば、onAnswerSelected パラメータにラムダ関数を渡すことで、ユーザーが選択したときにアクションを実行できるようになります。このラムダの定義で、selectedAnswer の値を新しいものに設定します。
onAnswerSelected
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun SingleChoiceQuestion(answers: List<Answer>) { var selectedAnswer: Answer? by rememberSaveable { mutableStateOf(null) } answers.forEach { answer -> SurveyAnswer( answer = answer, isSelected = (selectedAnswer == answer), onAnswerSelected = { answer -> selectedAnswer = answer } ) }}
var selectedAnswer: Answer? by
isSelected = (selectedAnswer == answer),
onAnswerSelected = { answer -> selectedAnswer = answer }
前回の記事を覚えているでしょうか?イベントは状態を更新する仕組みでした。この例では、ユーザーが選択肢をタップしたときに、onAnswerSelected イベントが実行されます。
Compose のランタイムは、状態が読み取られた場所を自動追跡しているので、その状態に依存するコンポーザブルを効率的に再コンポーズできます。そのため、状態を明示的に観測したり、手動で UI を更新したりする必要はなくなります。
コンポーズ可能な関数には、意識しておくべき動作特性がほかにもあります。この動作の特性上、コンポーズ可能な関数は、副作用をもたらさないことに加え、同じ引数で何度呼び出しても同じ動作になることが重要です。
1. コンポーズ可能な関数は任意の順序で実行できる
次のスニペットをご覧ください。このコードは順次実行されると思うかもしれません。しかし、必ずしもそうとは限りません。Compose は、一部の UI 要素の優先度が高いことを認識しているので、そのような要素は最初に描画される可能性があります。たとえば、タブレイアウトに 3 つの画面を描画するコードがあるとしましょう。StartScreen が最初に実行されると思うかもしれませんが、これらの関数はどのような順序でも実行することができます。
StartScreen
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() }}
fun ButtonRow() {
MyFancyNavigation {
StartScreen()
MiddleScreen()
EndScreen()
2. コンポーズ可能な関数は並列して実行できる
コンポーザブルは並列に実行できるので、複数のコアを活用することで画面のレンダリング パフォーマンスが向上します。次のコード スニペットでは、コードは副作用なく実行され、入力リストが UI に変換されます。
ただし、下のスニペットのように、関数からローカル変数に書き込みをする場合、コードは副作用なしとは見なされません。下のコードと同じようなことをすると、UI の動作が不適切になる可能性があります。
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun ListComposable(myList: List<String>) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") } } Text("Count: ${myList.size}") }}
fun ListComposable(myList: List<String>) {
Row(horizontalArrangement = Arrangement.SpaceBetween) {
for (item in myList) {
Text("Item: $item")
Text("Count: ${myList.size}")
3. 再コンポーズは可能な限りスキップする
Compose は、可能な限り、更新する必要がある UI のみを再コンポーズしようとします。再コンポーズをトリガーした状態を使わないコンポーザブルでは、再コンポーズがスキップされます。次のスニペットで name 文字列が変更された場合、Header コンポーザブルと Footer コンポーザブルはこの状態に依存していないため、再実行されません。
Header
Footer
// Copyright 2022 Google LLC. // SPDX-License-Identifier: Apache-2.0 @Composablefun GreetingScreen(name: String) { Column { Header() Greeting(name = name) Footer() }}
fun GreetingScreen(name: String) {
Header()
Greeting(name = name)
Footer()
4. 再コンポーズは厳密なものではない
再コンポーズは厳密なものではありません。つまり、再コンポーズはパラメータが再度変化する前に終わると想定されます。再コンポーズが終わる前にパラメータが変化した場合、Compose は再コンポーズをキャンセルし、新しいパラメータでもう一度再コンポーズを始める可能性があります。
5. コンポーズ可能な関数は何度も実行されることがある
最後に挙げるのは、コンポーズ可能な関数は何度も実行される可能性があることです。これが問題になるのは、コンポーズ可能な関数に毎フレーム実行する必要があるアニメーションが含まれる場合です。フレームの欠落が起きないようにするために、コンポーズ可能な関数を高速にすることが重要なのはそのためです。
長時間実行オペレーションが必要な場合は、コンポーズ可能な関数で行わないようにしてください。このようなオペレーションは、UI スレッドの外で実行し、コンポーザブルではその結果だけを渡すようにします。
また、コンポーザブルのいくつかの興味深い特性についても学びました。コンポーザブルには次の特性があります。
Compose ツールキットでは、基礎となる強力なコンポーザブルがたくさん提供されています。こういったコンポーザブルは、美しいアプリを作るうえで役立ちます。この点については、次回説明したいと思います。それまで待てない方は、以下のリソースを確認してみてください。
質問がある方は、下にコメントを記入するか、Twitter でハッシュタグ #MADCompose をお使いください。10 月 13 日に予定されている本シリーズのライブ Q&A で質問にお答えします。お楽しみに!( ※ライブ Q&A セッションは終了しました。録画はこちらからご確認いただけます。日本語字幕は、YouTube の自動字幕機能から日本語を選択してください。 )
¹ @Composable アノテーションがついた関数がすべて UI を返すわけではありません。たとえば、remember を呼び出す関数は UI を返しませんが、Compose UI ツリーのノードを生成します。
この記事は Yasmine Evjen による Android Developers Blog の記事 " Android Dev Summit ‘22: Coming to you, online and around the world! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Android Dev Summit (英語) が戻ってきます。そして2022 年は、皆さんがお住まいの場所で開催します!オンラインで視聴する方であっても、2019 年以来初めて世界各地で直接集まる方であっても、皆さんとお会いできるのが待ち遠しくてたまりません。デバイスに依存しない優れたアプリの構築について、ソースから学べる絶好の機会です。
Android Dev Summit ‘22 は、10 月 24 日の基調講演から始まります。基調講演では、Android チームから直接話を聞くことができます。最先端の Android 開発についての最新情報、私たちのコア プラットフォームのイノベーション、ウェアラブルや大画面などのさまざまなデバイスで Android の勢いを活用する方法についてお話しします。このテクニカル基調講演では、たくさんのデモも実演する予定です。10 月 24 日太平洋時間午前 9 時から始まり、YouTube でライブ配信します。
ADS で特に重要なのが、詳細なテクニカル セッションであり、私たちもとても楽しみにしています。2022 年は、3 週間にわたって 3 つのトラックのセッションを YouTube (動画/英語) でライブ配信します。
ADS は、皆さんと直接つながることができる機会です。皆さんが最も重視することや、Android での開発を楽にするために私たちができることについて、お聞きしたいと考えています。そのためには、直接お会いする以上の方法はありません。多くの皆さんにとって、長距離の移動はまだ難しいので、できる限り皆さんのもとに伺うようにしたいと考えました。そこで2022 年は、世界各地でイベントを開催します。ADS の最初の開催地は、10 月 24 日のサンフランシスコ ベイエリアです(近くにお住まいの方は、こちら (英語) から参加を応募できます)。その次の ADS ’22 は、11 月 9 日のロンドンです(ロンドンにお住まいの方は、こちら (英語) から参加を応募できます)。12 月には、アジアの何箇所かでロードショーをする予定です( ※日本での開催に関する詳細は後日共有予定です。 )
直接来ることはできない方にも、ぜひオンラインで参加いただきたいと考えています。各セッション トラックの最後には、ライブ Q&A として #AskAndroid を開催し、皆さんからの質問にお答えします。質問は、Twitter か YouTube ライブストリームのコメントに #AskAndroid を付けて投稿してください。ライブでお答えできるかもしれませんので、お楽しみに。
今後数週間にわたって、ADS ’22 の情報をウェブサイト (英語) に掲載します。全セッション トラックの詳細などを公開しますので、ぜひご覧ください。Android Developer ニュースレターに登録 (英語) すると、最新情報を受け取ることができます。
皆さんにお会いできることが楽しみです!
** 皆さん、こんにちは。Yasmine Evjen です。Android デベロッパー リレーションズで新しくコミュニティ リードを務めることになりました。#AndroidDevSummit で、皆さんと直接またはバーチャルでお会いできるのが楽しみです。私が大好きな 2 つのこと、つまりエクサイティングな新技術とそれに命を吹き込むデベロッパーの皆さんが 1 つになります。
この記事は Chris Arriola による Android Developers - Medium の記事 " Thinking in Compose " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Compose 基本シリーズのこの投稿では、Compose の考え方に迫りたいと思います。Jetpack Compose は宣言的 UI フレームワークです。つまり、デベロッパーは UI を表示する手順ではなく、表示する内容を記述します。
質問がある方は、この投稿か YouTube、または Twitter で #MADCompose を使ってコメントを残してください。10 月 13 日のライブ Q & A セッションで皆さんの質問にお答えします。
この記事の内容は、MAD Skills の動画でもご覧いただけます。
ビューを使う場合、現在の画面から望む画面にするために、UI を変更する手順を 1 つ 1 つ記述します。
たとえば、クリックしたボタンの背景色を変えたいとしましょう。ビューを使う場合、まず XML から初期状態の UI を読み込みます。その後、ユーザーがボタンをクリックしたときに、ボタンを探して setColor を呼び出します。望む画面状態になるまで、すべてのユーザーのインタラクションやプロパティに対してこれを繰り返します。
Compose を使う場合、望む状態になるまで個々の UI コンポーネントを変更する(詳しくは後ほど触れますが、これはエラーにつながりやすい操作です)必要はありません。表示する内容をあらかじめ宣言しておけば、画面の更新が必要になったタイミングでそのすべての内容が再宣言されます。
うれしいことに、XML で UI を記述する必要もなくなり、Kotlin の構造をフル活用しながら Kotlin だけで UI を記述できます。
手順ではなく内容を記述して UI を構築できる点が、Compose とビューの主な違いです。Compose の方がはるかに直感的に使えるのはそのためです。この記事では、この 2 つの違いに加えて、アプリ作成の考え方を Compose にどのようにシフトすべきか説明します。
Compose によるアプリ作成の考え方を理解するため、まずはビューでどのように画面を作るかについて確認しましょう。
次に示すのは、Github で公開されている Compose サンプルアプリの 1 つ、Jetsurvey の画面です。この画面には、ユーザーに回答を求める 1 択の質問が表示されています。いずれかを選択すると、次の質問に進むことができます。
説明を簡単にするため、この画面の中の 1 つのコンポーネント、すなわちアンケートの選択肢の 1 つを作る場合について考えます。
選択肢は、1 つのイメージ、何文字かのテキスト、ラジオボタンを水平に並べたものでできています。ビューでは、次のようにして各要素を XML で定義します。
<!-- survey_answer.xml --><LinearLayout android:orientation="horizontal" > <ImageView android:id="@+id/answer_image" ... /> <TextView android:id="@+id/answer_text" ... /> <RadioButton android:id="@+id/answer_radio_button" ... /></LinearLayout>
<!-- survey_answer.xml -->
<LinearLayout android:orientation="horizontal" >
<ImageView android:id="@+id/answer_image" ... />
<TextView android:id="@+id/answer_text" ... />
<RadioButton android:id="@+id/answer_radio_button" ... />
</LinearLayout>
このビューに UI の状態を設定するには、フラグメントかアクティビティで Kotlin か Java の findViewById を使い、それぞれのビューへの参照を取得します。参照を取得できたら、setImage や setText などのセッター関数を呼び出してそれぞれのビューを変更し、望む UI の状態を表示します¹。この手順では、それぞれのビューを個別に変更することで、初期状態の UI から望む UI の状態に更新します。つまり、状態を変更する手順を記述しています。 UI を表示する手順を記述すると書いたのはそのためです。
ユーザーが回答を選択すると(状態変化が発生すると)、選択されたことをビューで視覚的に表現しなければなりません。この例では、ユーザーが質問の回答を選択したときに、[Next] ボタンを有効にする処理も必要です。あるビューが選択されたときの副作用として別のビューを更新したい場合は、ビューにリスナーを設定して影響を受けるビューを明示的に変更します。
ただし、状態が変化したときに手動でビューを更新するという方法は、エラーにつながりやすくなります。ビューを状態に合わせて更新するのを忘れたり、複数の更新が予期しない形で競合したときに正しくない状態になったりする可能性があります。
たとえば、アプリで画面の回転などの構成変更が発生した場合、ユーザーが選択した内容は正しく覚えていたとしても、その過程で [Next] ボタンを再有効化することを忘れてしまうかもしれません。
アプリの生存期間全体にわたって状態の変化に同期することは、ビューを扱う場合に繰り返し遭遇する問題です。この問題の複雑さは、アプリでビューや依存する状態の数が増えるとともに増大していきます。これは解決できない問題ではありませんが、バグの原因になりがちです。
では、同じコンポーネントを Compose で作る場合、どのように考えるかみてみましょう。
Compose でも、先ほどと同じような形で UI を構築できます。つまり、イメージ、テキスト、ラジオボタンを水平に並べたコンテナを配置します。
ただし、XML を書く代わりに、要素を直接 Kotlin で定義します。
// SurveyAnswer.kt@Composablefun SurveyAnswer(answer: Answer) { Row { Image(answer.image) Text(answer.text) RadioButton(false, onClick = { /* … */ }) }}
// SurveyAnswer.kt@Composable
Compose の UI はすでに Kotlin で宣言されているので、XML と Kotlin を行き来する必要はなくなります。
Compose の UI 要素は関数であり、オブジェクトではありません。つまり、UI 要素は参照できないので、後からメソッドを呼び出して変更するようなことはできません。
その代わり、UI 要素のすべての制御は渡す状態(引数)によって行います。ここでは、単に UI に表示する内容を記述します。findViewById、setImage、setText を呼び出す必要はありません。UI は呼び出す関数の中に簡潔に記述します。
望みどおりの状態で UI を表示するため、回答のプロパティを Image 関数と Text 関数に、そして今のところ、未選択を示す false を RadioButton 関数に渡します。
ここでとても重要なビューとの違いがあります。それは、この回答をタップしても項目が選択されないことです。その理由は、RadioButton に常に false を渡しているからです。これは、ユーザーの操作に関係なく未選択のままにするという意味になります(まもなく修正しますので、心配は無用です)。
ビューとは違い、Compose の RadioButton はユーザーのイベントによって自動的に変化する状態を保持しません。RadioButton の状態は渡す値によって決まります。
先ほど、「手順ではなく内容」と述べたのはそのためです。UI 関数に必要な状態を渡すことで、UI として表示する内容を宣言します。UI の要素が変化した場合、新しい状態を渡して、すべてを再度呼び出します。一方のビューシステムでは、個々のパーツを手動で制御して、望みどおりの新しい状態を実現しなければなりません。
状態が UI を制御するなら、どうすれば状態を更新して UI を更新できるのでしょうか。Compose では、イベントを通じてこれを実現します。ユーザーが UI 要素を操作すると、UI は onClick などのイベントを発行します。すると、イベント ハンドラが UI の状態を更新すべきかどうかを決定します。
UI の状態が変化すると、その状態に依存する関数(UI 要素)が再実行されます。状態が変化したときに UI が再生成される処理を、再コンポーズと呼びます。状態を UI に変換する処理と、UI を再生成する状態の変化は、Compose が UI フレームワークとして動作する仕組みの中核です。
先ほどの SurveyAnswer コンポーザブルの RadioButton は、操作しても未選択のままでした。この実装を更新して、タップしたときに選択状態が切り替わるようにしてみましょう
まず、selected という boolean 型の変数を定義し、それを RadioButton 関数の引数として渡します。さらに、onClick イベント ハンドラで selected 変数の値を現在の値から逆転させます。こうすることで、クリックしたときに選択状態が切り替わります。この変更を終えると、RadioButton をクリックして選択状態を切り替えられるようになります。
// SurveyAnswer.kt@Composablefun SurveyAnswer(answer: Answer) { Row { /* ... */ var selected: Boolean = // ... RadioButton(selected, onClick = { selected = !selected }) }}
/* ... */
var selected: Boolean = // ...
RadioButton(selected, onClick = {
selected = !selected
})
なお、実際のアプリでは、RadioButton の状態は SurveyAnswer に持たせるのではなく、Answer オブジェクトから取得します。この例は、RadioButton の状態の仕組みを説明することのみを目的としています。
また、selected 変数を実装していない点にも注意してください。これを動作させるには特殊な状態オブジェクトが必要ですが、この点は次の記事で説明します。
以上の内容をまとめます。Compose の考え方は次のとおりです。
ここでは、Compose の考え方をとても大まかに説明しましたが、学ぶべきことはまだまだたくさんあります。
たとえば、Kotlin の関数はどのように動作するのか、状態とはどのようなものか、Compose では他にどのようなコンポーネントが提供されるのかといったことです。こういった内容は、今後のエピソードで説明します。
それまで待てない方は、以下のリソースを確認してみてください。
質問がある方は、下にコメントを記入するか、Twitter でハッシュタグ #MADCompose をお使いください。10 月 13 日に予定されている本シリーズのライブ Q & A でお答えします。お楽しみに!
¹ データ バインディング ライブラリもビューで宣言的にコードを記述する方法の 1 つです。この仕組みは本記事で説明した状態同期問題を回避するために役立つ可能性がありますが、Compose を使うと XML を扱う必要は完全になくなります。
Reviewed by Mari Kawanishi - Developer Marketing Manager, Google Play
この記事は Kat Kuan による Android Developers Blog の記事 " Learn Jetpack Compose at a Compose Camp near you! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。日本で開催される Compose Camp の詳細はこちらをご確認ください。
Jetpack Compose は、Android の UI 開発をシンプルにする Android の最新ツールキットです。Twitter、Airbnb (英語)、Google Play など、すでに世界中の多くのアプリで使われています。まだ使っていない方は、今が使い始める絶好のチャンスです。もっと簡単に Compose を学習していただくため、対面とバーチャルに対応したセッションとして、各地で Compose Camp (英語) を始めました。 (※ 日本で開催される Compose Camp の詳細はこちらをご確認ください。) Jetpack Compose を使って Android アプリを開発する方法を仲間と一緒に学ぶことができます。さっそく「キャンプ道具」を集めて、近くの Compose Camp (英語) に参加する方法を確認しましょう!
Jetpack Compose を使うと、コードの使用量と保守作業が少なくなるため、短期間でアプリを開発できます。また、API も直感的で強力なので、Android の最高の機能を使って優れたユーザー エクスペリエンスを提供できます。Google は、あらゆる人が Android 開発を学べるチャンスを増やせるようにする努力を続けており、その一環として、最新のベスト プラクティスをさまざまな学習スタイルで学んでいただけるようにしています。グループで学習を進めると、とても楽しく効果的に学べるという意見をたくさんの方からいただいています。それを受け、世界各地で Compose Camp (英語) を開催することにしました。ガイドしてくれる仲間や「キャンプ リーダー」のサポートを受けながら、Compose で Android アプリを開発する方法を学びましょう。
Android 開発が初めての方やプログラミングを始めたばかりの方は、Beginner トラックをご覧ください。基本的なプログラミングの考え方や、Jetpack Compose でユーザー インターフェースを作成する方法などのアプリ開発の基礎を学ぶことができます。
ビューから Compose に移行する方法を学びたい、あるいは高度な機能を使って UI を構築する方法を知りたいという Android デベロッパーには、Experienced トラックがおすすめです。Jetpack Compose のポイントから始めて、Compose のさまざまなトピックを掘り下げます。
他の人と一緒に学ぶと、コミュニティの一員としてアドバイスやサポートを受けられて楽しいという声がたくさんの方から寄せられています。Google デベロッパー コミュニティ (英語) は、同じ業界の学習者や仲間とつながりを持つ絶好のチャンスです。協力して技術的な難題に向かったり、お互いに技術を学び合って直接プロジェクトに活用したりできます。これからの数か月間、こういったコミュニティが世界中で Compose Camp を開催しますので、近くのイベントを探してみてください。 (※ 日本で開催される Compose Camp の詳細はこちらをご確認ください。)
イベントを開催して参加者に教えるのも、専門性を育む絶好のチャンスです。皆さん自身が「キャンプ リーダー」になる (英語) こともできます。学習に役立つ教材、セッションの進め方についてのガイド、サンプル スライド、参加グループを募るための資料など、Compose Camp を開催するために必要なものは、すべて揃えてあります。
「ソロキャンプ」の方が好きだという方は、自分のペースで学べるオンライン コースを確認しましょう。Android 開発を始めたばかりの方には、Android Basics with Compose コースがおすすめです。すでに Android 開発の知識をある程度お持ちの方は、Jetpack Compose for Android Developers コースをご覧ください。
ここで紹介したリソースが、Android 開発と Compose の学習に役立つことを願っています。Compose Camp (英語) で皆さんとお会いできるのを楽しみにしています。
この記事は Yuri Blaise による Android Developers Blog の記事 " Android Studio Dolphin " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
Android Studio チームは、高品質のアプリをより一層簡単に作れるようにするため、Android Studio Dolphin 🐬(2021.3.1)の最新安定版をリリースします。今回のリリースでは主に、Jetpack Compose、Wear OS、そして開発の生産性という 3 つのテーマに焦点を当てています。
Jetpack Compose に関しては、複数の画面やアニメーションを簡単にプレビューできる信頼性の高いツールを Android Studio Dolphin に搭載しています。また、アプリのユーザー インターフェースをデバッグする際に役立つように、UI の再コンポーズ回数を追跡できる便利な Compose UI カウンターを Layout Inspector に追加しました。
Android Studio Dolphin にはさまざまな Wear OS 機能を追加しているので、Wear アプリ、タイル、ウォッチフェイスはすべての Wear OS 3 デバイスに対応することができます。Wear OS エミュレータのアップデート、直感的なペア設定アシスタント、タイルやウォッチフェイスを追加するための新しいデプロイフローが搭載されているので、優れた WearOS アプリをこれまでよりも簡単に効率よく作ることができます。
さらに、Android Studio の生産性を一層向上するため、Gradle マネージド仮想デバイスを導入してテストデバイスを一元管理できるようにしました。
さっそく最新のアップデートをダウンロード (英語) して試してみてください。
以降では、Android Studio Dolphin に導入された新機能を詳しく説明します。または、こちらの動画をご覧ください。(動画/英語字幕あり)
この記事の内容をまとめます。Android Studio Dolphin には、以下の機能強化や新機能が搭載されています。
詳細は、Android Studio のリリースノート (該当箇所がまだ未翻訳のため、英語のページを参照ください) 、Android Gradle プラグインのリリースノート、Android Emulator のリリースノートをご覧ください。
最新バージョンの Android Studio Dolphin は ダウンロード ページ (英語) からダウンロードしてください。Android Studio の以前のリリースをお使いの方は、最新バージョンの Android Studio にアップデートするだけで利用できます。Android Studio の安定バージョンを保持する必要がある場合、Android Studio の安定リリース バージョンとカナリア リリース バージョンを同時に実行することができます。詳細はこちらをご覧ください。
上記の Android Emulator 機能を使用するには、Android Studio SDK Manager を介してダウンロードした Android Emulator v31.3.0 以降を実行している必要があります。
気に入った機能や問題点、新機能の提案などのフィードバックは大歓迎です。バグや問題を見つけた方は、お気軽に問題を送信してください。また、Android Studio 開発チームの Twitter (英語) や Medium (英語) をフォローしてください。
この記事は Fred Chung による Android Developers Blog の記事 " Privacy Sandbox: Developer Preview 5 is here! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
2022 年 9 月 7 日、Android 版プライバシー サンドボックスのデベロッパー プレビュー 5 をリリースしました。これは大きな節目であり、今後登場する予定のプライバシー サンドボックス ベータ版リリースの土台となるものです。
デベロッパー プレビューをテストし、問題の報告やフィードバックの共有をしてくださった大勢の皆さんに感謝いたします。寄せられたフィードバックは、プライバシー サンドボックスの設計が進化するうえで役立っています。たとえば、SDK ランタイムの設計を変更してリフレクション API の利用を許可したり、FLEDGE サービス、メディエーション、アプリとウェブにわたる測定といった設計提案を追加公開したりできました。
ここからは、今回のリリースの具体的な内容について説明します。
デベロッパー プレビュー 5 では、機能の追加、データ検証の強化、プライバシー保護 API と SDK ランタイム全般にわたる API シグネチャの変更などが行われています。詳しくは、リリースノート (最新情報は英語のみ) をご覧ください。
今後数か月間で、今回のデベロッパー プレビューを利用して新機能の導入と実装を進めます。ベータ版や今後のリリース予定の詳細は、改めてお知らせいたします。
今回のデベロッパー プレビュー リリースを活用し、デベロッパーの皆さんと連携して Android 版プライバシー サンドボックスの準備を進めていきたいと考えています。このリリースには、機能の早期テストを始めてフィードバックを共有するために必要なリソースが含まれています。開発を始めるには、エミュレータまたはサポート対象の Pixel デバイスで SDK とシステム イメージをセットアップする手順をご覧ください。
さらに詳しく Android 版プライバシー サンドボックス デベロッパー プレビューについて知りたい場合は、デベロッパー サイトをご覧ください。また、ニュースレターに登録すると、定期的に最新情報を受け取ることもできます。
この記事は Jolanda Verhoef による Android Developers Blog の記事 " Jetpack Compose 1.2 is now stable! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
2022 年 7 月 27 日、Android の最新ネイティブ UI ツールキットである Jetpack Compose のバージョン 1.2 をリリースしました。そして、引き続きロードマップを構築しています。今回のリリースには、ダウンロード可能なフォント、遅延グリッドといった新機能に加え、フォーカス、マウス、入力ハンドリングの改善といった、タブレットや Chrome OS 向けの機能強化が含まれています。
スマートフォン、タブレット、折りたたみ式向けに新しい Android アプリを開発する場合、私たちは Compose を推奨しています。今回は Compose for Wear OS 1.0 (英語) もリリースしたので、Wear OS アプリ開発でも Compose が最適な手段になります。
Twitter エンジニアリング チームなどのデベロッパーは、Compose を使って開発のスピードを上げています。
「Compose によって生産性が劇的に向上しました。コンポーズ可能な関数を書くのは、カスタムビューを作成するよりもはるかに簡単で速く、デザイナーの要件もたやすく満たせます」
Compose 1.2 には、スマートフォン、タブレット、折りたたみ式向けのたくさんのアップデートが含まれています。試験運用版から安定版になった新しい API があり、新しいバージョンの Kotlin もサポートされています。サンプル、Codelab、Accompanist ライブラリ、MDC-Android Compose Theme Adapter はすでにアップデートされ、Compose 1.2 対応になっています。
注 : Compose Compiler ライブラリを 1.2 にアップデートするには、Kotlin 1.7.0 が必要です。今後、Compiler のリリースは他の Compose ライブラリのリリースから切り離されます。この点に関する詳しい説明は、Jetpack Compose ライブラリが独立したバージョニングに関するブログ記事をご覧ください。
複数の機能や API が安定版として追加されました。主なものを紹介します。
Compose に新機能を導入する作業も続いています。いくつかの主な機能を紹介します。
@OptIn (英語) を使って新しい API を試し、フィードバックをお寄せください!
コミュニティから報告されたたくさんの問題を修正しました。主なものを紹介します。
Issue Tracker にバグレポートや機能リクエストをお送りいただき、大変感謝しています。Compose の改善や、皆さんに必要な API を作るうえで役立っています。Compose をより良いものにするために、今後もフィードバックをお願いします!
次に登場するのは何でしょうか。現在検討中または作業中の機能は、更新版のロードマップで確認できます。たとえば、項目の遅延追加や遅延削除時のアニメーション、フロー レイアウト、テキスト編集の改善などです。
Jetpack Compose は、皆さんから寄せられた要望をもとに進化し続けます。すでに多くのアプリで Jetpack Compose が本番環境として使われているのを見て、とてもうれしく思っています。そして、Jetpack Compose でアプリ開発がどのように改善したかを、皆さんの多くが共有しています。皆さんの次のアプリのリリースを楽しみにしています!
Compose をお楽しみください!
この記事は Roberto Orgiu による Android Developers - Medium の記事 " Make your app large screen ready " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
現在、Android は数十億台のデバイスで動作しています。スマートフォンはこのエコシステムの一部でしかありません。タブレット、折りたたみ式、そしてノートパソコンやデスクトップ PC までが Android アプリをサポートしているので、皆さんのアプリもさまざまなフォーム ファクタで動作することになります。
この記事では、大画面サポートを始める方法とその重要性について説明します。画面の向きの変化、アスペクト比、アダプティブ レイアウトを正確に扱うのは難しいことのように思えるかもしれませんが、新しい大画面エクスペリエンスを考えるなら、複数のフォーム ファクタに対応することでユーザーに新たなすばらしい可能性を提供することができます。
そこで私たちは、大画面デバイスを最大限に活用してもらうため、アプリの大画面対応を特に重視するように Google Play を大きく変更し、ユーザーが高品質なアプリやゲームを探し、活用できるようにしたいと考えています。さらに、Android 12L によって、デバイス メーカーは優先する画面の向きについてのアプリのリクエストを無視できるようになっています。これらの変更点は、こちらから確認できます。
すべての画面に対応することは難しく、アプリをすべての画面に対応させる際の考え方を変える必要があります。そこで、大画面サポートをいくつかのレベルに分割して考えます。アプリで提供できるサポートのレベルには、3 つの段階 (英語) があります。基本的な Tier 3 の大画面対応 では、どんな大画面デバイスでも全画面で問題なくアプリが動作することが求められます。次の段階は、アプリを大画面向けに最適化することです。Tier 2 の大画面最適化では、アプリを最適なレイアウトで表示し、拡張外部入力をサポートすることが求められます。最後に、最高のサポートレベルである Tier 1 の大画面差別化 では、大画面向けに完全に差別化したエクスペリエンスを提供します。
Tier DefinitionTier 3 Large screen readyTier 2 Large screen optimizedTier 1 Large screen differentiated
Tier Definition
Tier 3 Large screen ready
Tier 2 Large screen optimized
Tier 1 Large screen differentiated
この記事では、Tier 3 を始める方法と、アプリで大画面向けの最適化が重要な理由について説明します。
Tier 3 は、アプリが大画面デバイスで適切に動作するための第一段階です。以下のガイドに従い、アプリがすべての要件を満たすことと、ユーザーがすべての重要なフローを完了できることを確認しましょう。
縦向きのスマートフォンと横向きの大画面
構成の変化への対応は Android アプリ開発で常に基礎となるものですが、大画面デバイスでは特に重要です。先ほども述べたように、ユーザーは画面の向きを強制できます。しかし、考慮すべき構成の変化はほかにもあります。大画面では、物理キーボードの接続、ウィンドウのサイズ変更などのイベントが頻繁に発生します。新しいフォーム ファクタが利用できるようになった今、デバイスの持ち方もスマートフォンの持ち方と同じであるとは限りません。最初に考慮しなければならないのは、アプリがクラッシュせず、構成の変化の際に状態を保持しなければならない点です。これには、スクロールの位置やテキスト フィールドに入力されたテキストなどが含まれます。メディアの再生も、構成の変化が始まったときの続きから再開すべきでしょう。
これを実現する方法は複数あります。、ViewModel に状態を保存し、それを UI にプッシュすることから始めるとよいでしょう。しかし、ほかの API を使ってこれに対処することもできます。
マルチウィンドウ モードの折りたたみ式デバイス
複数のフォーム ファクタ、とりわけ大画面デバイスでは、ユーザーが一度に 1 つのアプリしか実行しないという考え方は通用しません。大画面では、ほかのアプリを一緒に実行するというのがほとんどのアプリの新基準になるはずです。そのため、この点に対応できるようにしておいた方がよいでしょう。
マルチウィンドウでは、アプリのライフサイクルについて再考し、それによって失われるリソースの喪失について調査しなければならないため、新たな課題が生まれますが、その対応も重要な一歩です。
マルチウィンドウと複数アプリの再開を進めるために、マルチウィンドウのサポートをご確認ください。
折りたたまれたデバイスと広げられたデバイスでのカメラの向き
大画面対応においては、カメラ機能を扱うことも非常に重要な作業ですが、これは特に難しい作業の 1 つでもあります。ユーザーはこのコンポーネントを、どのようなウィンドウ サイズでもあらゆる向きで利用できます。また、折りたたまれた状態でも利用できます。テーブルトップ モードなどの特殊な姿勢を活用したり、考えたことがないようなエクスペリエンスをファクタに応じて提供したりすることも検討できるでしょう。
カメラのプレビューを正しく表示し、正しい向きとアスペクト比でメディアを再生できることは、ユーザーにとって非常に重要です。そしてこの点も私たちがサポートします。今年の4月に、カメラアプリでサイズ変更可能なサーフェスを扱う際に役立つ新しい Codelabを公開しました。また、低水準 API にアクセスする必要がないなら、CameraX (英語) を使うこともできます。試してみたい方は、ExoPlayer によるメディア ストリーミングの Codelab やこちらのメディア プロジェクション API ガイドもご覧ください。
Android タブレットとキーボード、トラックパッド、タッチペン
大画面フォーム ファクタによって、ユーザーの選択肢がこれまでになく広がっていることを考えてみてください。たとえば、多くの新しいタブレットにはキーボードとトラックパッドが付属しており、ユーザーは外付け Bluetooth キーボードを使って大画面を活用するかもしれません。そのため、アプリを再起動することなく、仮想キーボードと物理キーボードを切り替えられることが重要です。
マウスとキーボードによる操作も忘れてはいけません。このような場合、タッチのサポートがない Chromebook などでは、上記のようなデバイスが唯一の入力ソースとなる場合があります。
以上のような可能性に対応する方法などについては、Android デベロッパー サイトで外部入力の処理をご確認ください。
すべての画面ですばらしいエクスペリエンスを実現するという考えは、アプリ開発の前提に疑問を投げかけるかもしれません。しかし、大画面フォーム ファクタに対応することは、アプリを堅牢で身近なものにする絶好のチャンスでもあります。Tier 3 のチェックリスト (英語) とテスト (英語) を参照し、アプリの大画面に対応するためのすべての要件を満たしていることを確認してください。そして、大画面対応に向けて次のステップを踏み出しましょう。
この記事は Seang Chau による Android Developers Blog の記事 " Android 13 is in AOSP! " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
8 月 15 日に、Android 13 のソースを Android オープンソース プロジェクト (AOSP) にプッシュし、Android の最新バージョンを正式にリリースしました。Android 13 のデベロッパー向け機能は、プライバシーとセキュリティ、デベロッパーの生産性という中核テーマに焦点を合わせており、ユーザーのために優れたエクスペリエンスを簡単に作れるようにします。また、Google は Android をタブレットや大画面にとって優れた OS にするための機能強化を続け、ツールの改善をして、世界中で使われている 2 億 7,000 万台以上の大画面デバイスを活用できるようにしています。ユーザー向けの Android 13 の機能の詳細は、The Keyword の記事 (英語 / 和訳はこちら) をご覧ください。
8 月 15 日より、Pixel デバイスへの Android 13 の配信が始まりました。今年中には、皆さんの Samsung Galaxy、ASUS、HMD (Nokia 製スマートフォン)、iQOO、Motorola、OnePlus、Oppo、realme、シャープ、Sony、TECNO、Vivo、Xiaomi などのデバイスにも Android 13 が配信されます。
いつものように、皆さんが寄せてくださったフィードバックに感謝いたします。また、アプリで 8 月 15 日のリリースへの互換性を確保する作業をしていただいたことにも感謝しています。Android があらゆる人のための偉大なプラットフォームであるのは、皆さんのサポートや貢献があってこそです。
ここでは、Android 13 の新機能の一部を紹介します。Android 13 デベロッパー サイトでは、すべての新機能について詳しく説明しているので、そちらもご覧ください。
テーマ対応アプリアイコン - Android 13 では、Material You のダイナミック カラーをすべてのアプリアイコンに拡張し、ユーザーが壁紙の色合いなどのテーマ設定を継承したアイコンを利用できるようにします。アプリで必要なのは、モノクロのアプリアイコンを提供し、アダプティブ アイコンの XML を微調整するだけです。詳しくはこちらをご覧ください。
アプリごとの言語設定 - Android 13 では、システム言語とは違う言語でアプリを使いたい多言語ユーザーを簡単にサポートできるようになっています。この機能をオプトイン (英語) したアプリには、標準の [App language] 設定パネルが表示されます。新しいプラットフォーム API (英語) を呼び出すと、実行時にユーザーが希望する言語 / 地域を取得したり設定したりできるので、ボイラープレート コードを減らして互換性の向上をすることができます。詳しくはこちら (英語) をご覧ください。
テキスト サポートの改善 - Android 13 にはテキストと言語の改善が含まれており、さらに洗練されたエクスペリエンスを提供できます。ハイフネーションの高速化では、ハイフネーションのパフォーマンスを最適化して 200% 近く向上させ、TextView で有効化してもレンダリング パフォーマンスにほとんど影響を与えなくなっています。テキスト変換 API は、日本語や中国語などの表音文字入力を使う場合に、検索やオートコンプリートを高速化します。Android 13 では、非ラテン文字(タミル文字、ビルマ文字、テルグ文字、チベット文字など)の行の高さの改善も行っているので、表示の際に文字が切れることはなくなり、読みやすくなります。詳しくはこちらをご覧ください。
カラー ベクター フォント - Android 13 では、COLR バージョン 1 (仕様 (英語)、紹介動画 (英語) ) フォントのレンダリングがサポートされ、システムの絵文字が COLRv1 形式にアップデートされます。COLRv1 は、非常にコンパクトな新しいフォント形式で、サイズを問わず高速にくっきりと表示できます。システムがすべての処理をしてくれるので、ほとんどのアプリでは何もしなくても動作します。詳しくは こちら (英語) をご覧ください。
クイック設定配置 API - Android 13 では、カスタムのクイック設定タイル (英語) を提供するアプリで、ユーザーが簡単にタイルを見つけられるようになります。新しいタイル配置 API (英語) を使うと、アプリを離れることなく、1 つの手順でカスタムのクイック設定タイルを直接追加するプロンプトを表示できます。詳しくはこちらをご覧ください。
プログラマブル シェーダー - Android 13 では、プログラム可能な RuntimeShader (英語) オブジェクトが導入されます。このオブジェクトの動作は、Android Graphics Shading Language (AGSL) (英語) で定義できます。このシェーダーを使うと、アプリでリップル、ブラー、ストレッチなどの高度な効果を作成できます。詳しくはこちら (英語) をご覧ください。
PlaybackState からのメディア コントロールの導出 - Android 13 をターゲットとしているアプリでは、システムが PlaybackState (英語) アクションからメディア コントロールを導出します。これにより、すべてのスマートフォンやタブレット デバイスで一貫した高度なコントロールが可能になり、Android Auto や Android TV などの他の Android プラットフォームとの整合性も向上します。詳しくはこちらをご覧ください。
Bluetooth LE Audio - 次世代ワイヤレス オーディオである LE (低電力) Audio (英語) は、友だちや家族にオーディオを共有またはブロードキャストしたり、情報や娯楽、ユーザー補助を目的として一般公開されているブロードキャストをサブスクライブしたりするといった新しいユースケースを実現します。また、電池寿命を犠牲にすることなく、非常に再現性の高いオーディオを受信し、ユースケース間でシームレスな切り替えができるように設計されています。Android 13 は LE Audio をビルトインでサポートするので、デベロッパーは互換デバイスで新機能を利用できます。詳しくはこちら (英語) をご覧ください。
MIDI 2.0 - Android 13 は、新しい MIDI 2.0 規格 (英語) をサポートします。これには、USB 経由で MIDI 2.0 ハードウェアに接続する機能も含まれます。この最新規格では、コントローラの分解能の増加、西洋以外の音調のサポート強化、音符単位のコントローラによる演奏の表現力向上などの機能が提供されます。詳しくはこちら (英語) をご覧ください。
OpenJDK 11 アップデート - Android 13 では、コア ライブラリを OpenJDK 11 LTS リリースに合わせています。これには、ライブラリのアップデートと、アプリやプラットフォーム デベロッパー向けの Java 11 プログラミング言語のサポートの両方が含まれます。また、Google Play システム アップデートにより、さらに多くのデバイスにコア ライブラリの変更を提供することを計画しています。このアップデートは、Android 12 以降を実行するデバイスを対象に、ART モジュール アップデートの一環として行う予定です。詳しくはこちらをご覧ください。
予測可能な「戻る」ジェスチャー - Android 13 には、「戻る」イベントを処理することを事前にシステムに伝えるための新しい API が導入されます。これは Ahead-Of-Time モデルと呼ばれる手法です。この新しいアプローチは複数年にわたる作業 (動画/英語) の一環であり、予測可能な「戻る」ジェスチャーをサポートできるようにします。今回のリリースではデベロッパー オプションからテストできるようになっています。詳しくはこちら (英語) をご覧ください。
Android 13 は今年リリースした 12L アップデート (英語) を拡張したもので、タブレットでのエクスペリエンスがさらに改善されています。マルチタスク用ツールバーの強化、システム UI やアプリでの大画面向けのレイアウトや最適化の継続、アプリの互換性モードの改善などの機能が含まれています。タブレットや Chromebook、折りたたみ式ですばらしいエクスペリエンスを実現するツールを提供する取り組みは、現在も継続しています。詳細については、大画面向けの最適化を始める方法や、大画面デベロッパー リソースをご覧ください。
写真ピッカーと API - システムの新しい写真ピッカーが、プライバシーを保護しつつローカルやクラウドにある写真を共有する標準的な方法を提供します。写真ピッカーは、Android で長年使われているドキュメント ピッカーを拡張し、ユーザーが特定の写真や動画をアプリと簡単に共有できるようにします。デバイス上のすべてのメディア ファイルを参照できるパーミッションをアプリに付与する必要はありません。写真ピッカーでは写真や動画に特化した操作ができるようになっており、アプリから共有メディア ファイルにアクセスする API が含まれています。この写真ピッカーは、Google Play システム アップデートを受信している Android 11 以降のデバイス(Go デバイスは除く)で利用できます。詳しくはこちら (英語) をご覧ください。
通知パーミッション - ユーザーが最も重要な通知に集中できるようにするために、Android 13 には新しい通知ランタイム パーミッション (英語) が導入されます。アプリは、通知を送信する前に、ユーザーに対してこの通知パーミッションをリクエストする必要があります。Android 12 以前をターゲットにするアプリでは、システムがアップグレード フローを処理します。詳しくはこちら (英語) をご覧ください。
近くにあるデバイスの Wi-Fi パーミッション - Android 13 では、近くにあるアクセス ポイントへの Wi-Fi 接続を管理するアプリに対して、NEARBY_WIFI_DEVICES (英語) ランタイム パーミッションを導入します。新しいパーミッションは多くのよく使われる Wi-Fi API に必要で、Wi-Fi 経由で近くにあるデバイスを検出したり接続したりできるようにします。その際に、位置情報のパーミッションを取得する必要はなくなります。詳しくはこちら (英語) をご覧ください。
メディア ファイルにアクセスする細かいパーミッション - 写真や動画を共有する場合は、ユーザー フレンドリーでパーミッションが不要なソリューションである写真ピッカーがお勧めですが、Android 13 では、まだ写真ピッカー (英語) に移行していないアプリやオーディオを扱うアプリのために、細かいメディア パーミッションを追加しています。この新しいパーミッションは READ_EXTERNAL_STORAGE (英語) パーミッションに替わるもので、イメージ、動画、オーディオなど、特定の種類のメディア ファイルにアクセスできます。可能な限り、アプリを写真ピッカーに移行することをお勧めしますが、それができない場合は、Android 13 をターゲットにするときに細かいメディア パーミッションをお使いください。詳しくはこちらをご覧ください。
デベロッパーがダウングレード可能なパーミッション - Android 13 より、ユーザーが以前に付与したパーミッションが不要になったアプリで、新しい API (英語) を使ってパーミッションをダウングレードできます。使わなくなったパーミッションを削除することで、必要最低限のパーミッションのみ使うことを示せるので、ユーザーの信頼が向上します。詳しくはこちらをご覧ください。
インテント フィルタの安全なエクスポート - Android 13 をターゲットにしたアプリでは、別のアプリからエクスポートされたインテント フィルタに明示的インテントを送る際に適用されるルールが厳格化されます。アクションを指定するインテントについては、受信側で宣言された <intent-filter> 要素にインテントが一致する場合にのみ、システムにより、エクスポートされたコンポーネントにインテントが送信されます。詳しくはこちらをご覧ください。
Android 13 では、ART ランタイムのアップデートにより、すべてのアプリのパフォーマンスと効率が向上しています。また、Google Play システム アップデートにより、さらに多くの Android ユーザーに改善を提供することを計画しています。このアップデートは、Android 12 以降を実行するデバイスを対象に、継続中の ART モジュール アップデートの一環として行う予定です。
ガベージ コレクションの改善 - 今後の Google Play システム アップデートで、Android 13 デバイスの ART に、Linux カーネル機能 userfaultfd に基づいた新しいガベージ コレクタを導入します。新しいガベージ コレクタでは、読み取りのバリアがなくなり、読み込まれたオブジェクト当たりの固定オーバーヘッドもなくなるため、メモリ負荷が減少し、コンパイル済みのコードのサイズが最大 10% 縮小します。圧縮が進むにつれてページが解放されるので、GC 時間の効率も上がります。新しいガベージ コレクタを使うと、電池の節約、GC 実行中のジャンクの回避、低メモリによるアプリ終了の防止といった全般的な効果を得ることができます。
ART の全般的な最適化 - Android 13 では、ART によってネイティブ コードとの間の切り替えや切り戻しが大幅に高速化され、JNI の呼び出しが最大 2.5 倍高速になっています。また、ランタイムの参照処理を再構築し、ほぼブロックが発生しなくなったことで、さらにジャンクが減少しています。新しいパブリック API である Reference.refersTo() (英語) も公開しました。この API は、到達不能なオブジェクトをすぐに再利用したい場合に役立ちます。また、クラスやメソッドの検索を最適化することで、インタープリタも高速化しました。さらに、ART が行うインストール時のバイトコード検証が増加しているので、実行時の検証コストが下がり、アプリの起動時間が短縮されています。詳しくはこちら (動画/英語)をご覧ください。
8 月 15 日、Android 13 が AOSP に一般公開リリースされたので、ユーザーがスムーズに Android 13 に移行できるようにするために、すべての Android デベロッパーの皆さんに互換性テストを終えて、できる限り早くアップデートを公開することをお願いします。
アプリの互換性をテストするには、Android 13 が動作するデバイスにインストールし、アプリのフローを確認して機能や UI の問題を探します。まず、Android 13 でのすべてのアプリが対象となる動作の変更点を確認し、現在のアプリが影響を受ける可能性がある領域を集中的にテストしてください。特にテストしておくべき変更点は、以下のとおりです。
アプリのライブラリや SDK の互換性テストも忘れずに行ってください。SDK の問題を見つけた場合は、最新バージョンの SDK にアップデートするか、デベロッパーに連絡してサポートを求めてください。
現行のアプリについて互換性のあるバージョンを公開すると、アプリの targetSdkVersion をアップデートするプロセスを開始できます。Android 13 をターゲットとしたアプリの動作の変更点を確認し、互換性フレームワークを使って問題をすばやく検知します。
Android 13 によってタブレットのエクスペリエンスが向上するので、アプリが最適な見栄えになるようにしてください。Android Studio で Android エミュレータをセットアップすると、大画面機能をテストできます。または、Android 13 ベータ版パートナー (英語) の大画面デバイスを使うことができます。以下に、注意すべき点を示します。
Android 13 のタブレット機能とテスト内容の詳細は、こちらからご覧ください。
8 月 15 日より、Pixel デバイスへの Android 13 の配信が始まりました。
現在 Android ベータ版プログラムに登録している方は、Android 13 の最終リリースを受け取ります。登録は今後も継続されるので、今年中に始まるベータ版アップデートで Android 13 の機能の追加を受信できます。デバイスをワイプせずにベータ版アップデートの登録を解除したい方は、Android 13 最終リリースを受け取ってから、Android 13 の機能の追加のベータ版を初めて受け取るまでの間に、Android ベータ版サイトにアクセスしてオプトアウトをしてください。
Pixel デバイス用のシステム イメージもこちら (英語) で公開しています。手動でダウンロードして更新する際に使用できます。最新の Android Emulator システム イメージは、Android Studio の SDK Manager から入手できます。Android 13 のソースを探している方は、Android オープンソース プロジェクトの Android 13 ブランチの下にあるリポジトリにあります。こちら (英語) をご覧ください。
繰り返しますが、早期プレビューやベータ版のプログラムにご参加いただき、ありがとうございました。Android 13 に対応した皆さんのアプリを楽しみにしています。
Java および OpenJDK は Oracle および/またはその関連会社の商標または登録商標です。