Open28
Android Dev Summit 2021の個人的に気になったところのメモ
The Android Show (Keynote)
- アプリの事例の紹介をいくつか
- Android12の話し
- Deeply personal
- Material Youとかの話し
- Secure by default
- Android's Private Comute Core
- Google Play
- Protect
- new data safety section
- Better together
- Samsungと協力してWear OS新しいを開発の話し
- スマホがAndroid TVとGoogle TVのリモコンになる話
- 文字入力がかなり楽ちん
- 大画面デバイスの話し
- 2.5億ものアクティブな大画面デバイスがあるよ
- Deeply personal
- MADの話し
- Kotlin
- KSP
- Compose
- 1.1 Now in Beta!
- Live editingのデモ
- Paddingの変更が即座にPreviewとDeviceに反映されるデモ
- アニメーションめっちゃ楽だよ、というデモ
- Material You
- GoogleのGmail, Calendar, Calculatorが良い例だよ
- Android View用にMaterial Youのコンポーネントをリリースしたよ、Compose用はPreviewだよ
- Profile APK
- パフォーマンスを保ったまま、アプリのプロファイルが取れるよ
- Spotifyの事例紹介
- Auto/Phone/Foldable/Wear でシームレスな体験の話し
- 様々なスクリーンサイズへの対応の話し
- Google Photoの話し
- 大画面に適した改修をした結果、DAUが約50%向上したよ
- Material Youと大画面に対応したサンプルアプリの話し
- WindowManager 1.1でwindows size classとして画面の大きさの情報を提供するよ
- resizableなエミュレータがAdaptiveなUIの開発で便利だよ
- Google Photoの話し
- Android 12Lの話し
- Activity embeddingの話し
- タブレットではLenovo P12ProでもうすぐDepeloper Previewが使えるようになるよ
- 2022年初頭に一般公開しようと準備しているよ
Modern Android Development #AskAndroid | LIVE
- Kotlin flowをUIで安全にcollectする方法は?
- repeatOnLifecycle使いましょう
- flowWithLifecycleも使えるけど、実質的には同じだよ
- MVVM or MVI?
- どちらも大きな違いは無く、我々が推奨している単方向データフローを実現できる
- ユーザーの意図をモデル化したい、よりリアクティブにしたいならMVIなのかも?ぐらいの差
- RepositoryをViewModelからObserveする良い方法は?
- Flowです
- より一般化すると、ライフサイクルが短いもの(例:ViewModel)から長いもの(例:Repository)をObserveするようにしてください
- これは、単方向データフローの実現とも繋がります
- 例えば、ViewとViewModel間でもこれ当てはまります
- LiveDataは?問題無いですよ!
- ただ、LiveDataはUI用の用途が明確なクラスです
- たとえば、Repositoryのinterfaceとして提供するのは不適切です
- 特にKotlin coroutinesを使っている場合にLiveDataを使用する理由はほとんどありませんが、より簡単だと思う場合は使用できます
- しかし、LiveDataをUI層以外に使用する事は避けて下さい
- ただ、LiveDataはUI用の用途が明確なクラスです
- flowよりLiveDataが適切なケースがありますか?
- LiveDataは特定ユースケースに最適化されているが故に、スケールしません
- https://medium.com/androiddevelopers/migrating-from-livedata-to-kotlins-flow-379292f419fb を読んでみてください
- LiveDataの方がより自分にとって適切だという場合は、引き続き使用する事が出来ます
- 非推奨ではありません
- ただ、LiveDataを使わない場合は使用するテクノロジーが一つ減ることになるので、メンテナンスが容易になると思います
Deep dive into Jetpack Compose layouts
- 基本的な話し
- CompositionでUIツリーを作る
- その後、Layoutのステップでサイズや位置を決めて、最後の描画する
- LayoutではMeasureとPlaceがある
- 雑に言うと従来のViewと同じだが、Composeのそれは絡み合っている
- Layout Composable
- 全てのComposableに1つ以上のLayout Composableがあり、これはLayoutNodeを送出する
- UIツリー or CompositionはLayoutNodeのツリーである
- MeasurePolicyを受け取ることができる
- カスタムレイアウトを作るとき、コレを元に配置を決める事が出来る
- MeasurePolicyが受け取るConstraintsはでサイズの制約を表現している
- 最小最大サイズ、固定のサイズや、可能な限り大きく、など
- 同様にList<Measurable>は計測対象である(子Composable)
- シンプルなケースではMeasurable#measure(constraints)で計測でき、Placableが得られる
- その後、これらを配置していく
- 全てのComposableに1つ以上のLayout Composableがあり、これはLayoutNodeを送出する
- Custom Layoutの話し
- GridLayoutの例
- 子Composableの中の最大幅を算出したら、これをmin/maxWidthとしてconstraints.copyしたあと、measureする
- このように新しい制約にすることで、カスタムレイアウトを実現できる
- 子Composableの中の最大幅を算出したら、これをmin/maxWidthとしてconstraints.copyしたあと、measureする
- 従来のViewと異なり、各Composableの計測は1回だけ
- 親は子に制約を伝え、子はその制約の範囲で計測・配置し、親はこれを受け入れなければいけない
- 実際、2回計測しようとすると例外吐くよ
- 親は子に制約を伝え、子はその制約の範囲で計測・配置し、親はこれを受け入れなければいけない
- JetSnackのCustomBottomBarは、Layoutで実現した特定用途のComposableの例だよ
- 計測しやすいよう、layoutIdを指定して、このlayoutIdで探して計測しているよ
- このようなアニメーションは、従来のViewシステムではパフォーマンスの観点で難しかった
- Layout animationは現在取り組んでいるので、将来的には独自のLayoutを作らなくても実現できる予定だよ
- GridLayoutの例
- ModifierがどのようにLayoutに関わってくるのかの話し
- LayoutModifierはmeasureメソッドを持っていて、MeasurableとConstraintsを受け取るよ
- リストでは無く単一である事を除けば、Layout Composableと同様だよ
- 制約や配置の変更も可能、つまり一つのComposableに作用したいだけなら、Custom Layoutを作らなくてもModifierで対応できる
- PaddingModifierの例
- まずサイズの制約を、Padding分だけ減らす
- そして、オフセットされた位置に配置している
- Modifierによるカスタムレイアウト
- Modifier.layout で可能
- リストでは無く単一である事を除けば、Layout Composableと同様だよ
- Boxを中央に配置する例でModifierがどのように作用するかを説明
- 順番が重要な事も
- LayoutModifierはmeasureメソッドを持っていて、MeasurableとConstraintsを受け取るよ
- Advanced features(便利だが、注意が必要なものたち)
- Intrinsic Measurement
- 実は必ずしも1回だけでレイアウトが確定するとは限らない
- 例としてメニューポップアップ
- Modifier.width(IntricsicSize.Max) が使える
- 子の中で一番大きなサイズ、という意味
- Modifier.width(IntricsicSize.Max) が使える
- ParentData
- Modifierは汎用的なものだけど、例としてBoxのModifier.alignはBoxScopeでしか使えない、子が親に情報を伝えるためのもの
- どうような事が独自のCustom Layoutでもできるよ
- Intrinsic Measurement
- Alignment Lines
- 例としてRowの中でTextに対してalignByBaseline()して、IconはalignByすると、Iconの位置をTextのベースラインに合わせられる
- カスタムレイアウトでも独自にこのような事ができる
- BoxWithConstraints
- contentのCompositionを、レイアウト情報がわかるまで遅延させる
- これにより、サイズに応じたレイアウトに切り替える事が容易にできる
- contentのCompositionを、レイアウト情報がわかるまで遅延させる
- Performance
- JetsnackのCoordinatorlayoutの例
- スクロールポジションをどこで監視するかがパフォーマンス観点で重要
- Modifier.offset { } を使う事でModifierの再生成が不要となる
- Placementのステージでoffsetに渡したラムダが実行されるだけとなる
- Modifier.offset { } を使う事でModifierの再生成が不要となる
- 原則として、頻繁に変更されるComposableのパラメーターやmodifierがあれば、これはパフォーマンスの問題を引き起こす可能性がある
- あくまでrecomposiitonは表示したい
内容
が変わったときのみ起きるようにするべき -
どこに、どのように配置するか
でrecompositionが起きないようにしましょう
- あくまでrecomposiitonは表示したい
- BoxWithConstraintsは何をしているのか?
- Layout中にCompositionをおこなっている
- ただし、これはパフォーマンスの観点で極力避けたい
- BoxWithConstraintsより、サイズによって変わるレイアウトを使う方が好ましい
- Layout中にCompositionをおこなっている
- スクロールポジションをどこで監視するかがパフォーマンス観点で重要
- JetsnackのCoordinatorlayoutの例
A Compose state of mind: Using Jetpack Compose's automatic state observation
- Jetsnakを例に今回は説明するよ
- 普通の変数だとComposeにtrackされないよ
- 例:mutableStateOf(1)で定義すればOK
- かつ、recomposeでも再初期化されないように書く必要があるよ
- 例:remember { mutableStateOf(1) } で定義すればOK
- rememberSaveable もあって、こちらはActivityやProcessの再生でも復元されるよ
- Stateは常にComposable関数の外で変更するようにしましょう(onClickやSideEffectで)
- Composable関数は高頻度に実行されるため
- Composable関数を再利用可能とする場合
- StateをComposableの中のonClickなどで変更する場合、初期値はImmutableで渡すべきだよ
- Single source of truthの原則を守るため
- 値の変更自体は、これを渡されたlambdaを呼び出して通知してあげるのが良いよ
- これはstate hoistingと呼ばれているよ
- 既存のComposableでもコレは用いられていて、state hoistingが不要な場合用にデフォルト引数でStateを受け取っているよ
- StatelessとStatefullの両バージョンのComposableを作るのが再利用性の観点からオススメだよ
- StateをComposableの中のonClickなどで変更する場合、初期値はImmutableで渡すべきだよ
- Stateとロジックを種類別にわけてそれぞれどう保持するのが良いかを考える
- JetsnackAppStateを例に説明
- これはplainなclass(not Composable)
- ここで、ScaffoldStateや、ボトムバーを出すべきかどうか、どこに画面遷移するかなどを管理している
- Composableなプロパティを提供している
- AACのViewModelもStateHolderとして使えるよ
- ConfigChangeを超えて保持される点には注意が必要だよ
- つまり、Composableよりライフサイクルが長くなる事があり得るよ
- なので、Composableで作られたStateを受け取らないように注意
- メモリリークが発生する可能性あり
- 使う場合はScreenLevelが推奨だよ
- 色々な利点(ConfigChange、Cached in backstack)があるけど、これらが不要であればplainなclassでstate holderを実現するのが好ましいよ
- もちろん、ViewModelとplain classなState Holderの両方を使う事もできるよ
- plainなState HolderにLazyListStateを保持するなど
- ConfigChangeを超えて保持される点には注意が必要だよ
- JetsnackAppStateを例に説明
- 普通の変数だとComposeにtrackされないよ
A deep dive into what's new in Room 2.4.0
- Auto Migrations
- 前後のエクスポート済みスキーマを指定するだけで自動マイグレーションできるよ
- 例えばフィールド名変更は12ステップものSQL操作が必要だけど、これも少しコードを書けば自動マイグレーションできるよ
- AutoMigrationSpec interfaceを実装してアノテーションを記述すればOKだよ
- DeleteColumn, DeleteTable, RenameColumn, RenameTable が利用できるよ
- AutoMigrationSpec interfaceを実装してアノテーションを記述すればOKだよ
- 例えばフィールド名変更は12ステップものSQL操作が必要だけど、これも少しコードを書けば自動マイグレーションできるよ
- テストはMigrationTestHelperでできるよ
- AutoMigrationよりCustomMigrationが優先されるのは注意してね
- 前後のエクスポート済みスキーマを指定するだけで自動マイグレーションできるよ
- Relational Query
- @Queryアノテーションで単純なMapを返す関数を記述できるようになったよ
- one-to-one, one-to-many の両方対応だよ
- @MapInfoでMapのためのkeyとなるColumnを指定できるよ
- ただし、keyはequalsとhashCodeが実装されている必要があるよ
- @MapInfoによって、例えばGROUP BYも簡単に書けるよ
- @Queryアノテーションで単純なMapを返す関数を記述できるようになったよ
- Eum Type Converters
- デフォルトで文字列にして保存&その逆もできるようになったよ
- Query Callback
- database builderにQueryCallbackを登録して、実際にどんなクエリーが実行されているかログが取れるようになったよ
- KSPを実験的にサポートしたよ
- KSPがstableになったら、例えばValue Classなどの待望されているサポートをおこなうよ
WorkManager: Back to the foreground
- 最初のstable releaseから追加されたもの
- 即座に実行可能なフォアグランドなタスクもハンドリングできるようになったよ
- 例:写真にフィルターを適用してローカルに保存後、アップロード
- マルチプロセスのサポート
- 例えば大規模なアプリ向けに
- テストのサポート
- ツールによるサポート
- 即座に実行可能なフォアグランドなタスクもハンドリングできるようになったよ
- これらにより、いつWorkManagerを使うべきか再考することにしたよ
- WorkManagerは、永続的な処理に推奨されるライブラリとなったよ
- 永続的な処理とは?
- ActivityのonDestoryやconfiguration changed後も生き残る
- Roomを使用する事で、プロセスが死んだりデバイスがリブートしてもレジュームが可能
- Long running work
- 10分以上の処理を実行できる
- フォアグラウンドサービスとライフサイクルのバインドが必要
- キャンセル可能
- 通知からキャンセルを簡単に実装できるよ
- Android 12のForeground Service Restricitons
- WorkManagerで対応したよ
- マルチプロセスのサポート
- 例えばどういうときに使う?
- ML専用の処理を別プロセスで実行し、仮にMLのプロセスが落ちてもメインのプロセスには影響を与えない
- 例えばどういうときに使う?
- ツールの改善
- App InspectionのBackground Task Inspector
- 更なる情報
- goo.gle/mad-workmanager
Implementing Material You using Jetpack Compose
- Compose Material 3がα版としてリリースされたよ
- サンプルとしてJetchatのMaterial 3対応を進めているよ
- 配色を新しいMaterial Theme Builderツールで作っているよ
- Colorクラスを生成できるよ
- Dynamic Colorにも対応できるよ
- Android12以上のみでサポート
- 自動でライトとダークなカラースキームを生成できるよ
- Typography
- Material2に比べて簡略化したよ
- 種類をしぼり、それらのLarge/Medium/Smallに分けたよ
- Material2に比べて簡略化したよ
- Elevation
- 影ではなくtonal color overlaysで表現されるようになったよ
- elevationを上げる=目立つトーンの色になるよ
- Material 3のライブラリではtonalElevationとして指定できるよ
- 影ではなくtonal color overlaysで表現されるようになったよ
- Updated components
- 色々アップデートされているよ
- BottomNavigationはNavigationBarに名前が変わったよ
- Compose Material CatalogのMaterial 3セクションを確認するのがお勧めだよ
- Ripple & overscroll
- Rippleはかすかな輝きのようなエフェクトになったよ
- スクロールは端っこでストレッチするエフェクトがかかるようになったよ
- MDC-Android Compose Theme Adapter
- XMLで書いたThemeをComposeでも使えるよ
- これのMaterial 3対応版を用意したよ
- XMLで書いたThemeをComposeでも使えるよ
New features in ML Kit: Text Recognition V2 & Pose Detection
- Text Recognition V2
- ラテン系以外の言語をサポートしているよ(日本語など)
- ブロックや段落の考慮もおこなうよ
- 色々な方向に書かれたテキストも認識できるよ
- Pose Detection
Support the latest and greatest: Compatibility changes in Android 12
- User interface
- スプラッシュスクリーン
- cold or warmでの起動時
- Custom notifications
- 全部のエリアがカスタマイズ可能ではなくなったよ
- Immersive mode for gesture navigation
- デフォルトではフルスクリーンでも1回の操作でジェスチャーナビゲーションが効くようになったよ
- Foreground service launch restrictions
- Expedited jobs
- Exact Alarm permission
- Notification trampolines
- App Links changes
- Deep Linksとは異なりHTTP schemaしか処理できない
- スプラッシュスクリーン
- Android12対応の例
- ストレッチスクロール
- RecylerViewの外で書いていた背景がストレッチされない問題
- ItemDecorationで書くことで解決
- ストレッチスクロール
Building great experiences for Novice Internet Users
- NIU = Novice internet users
- 軽量なアプリバージョンを提供する事が適切とは限らない
- 習熟しているユーザーと異なるUXだと、彼らから学ぶのが難しくなる
- フルバージョンに移行すると、全てを学び直す必要がある
- Account creation
- デジタルアカウントという概念が難しい
- アカウントをサービスごとに作る必要がある、という概念が難しい
- サービスを使うメリットがわからないのに、電話番号などの個人情報を提供するのは躊躇ってしまう
- そのため、例えばアカウントを家族で共有する
- アカウント作成が難しいため
- Language options
- インドなどのマルチリンガルな国では端末自体は英語でセットアップされている事がある
- しかし、英語に流暢な人ばかりではない
- デバイスの設定とは別にアプリの言語を切替できる事が望ましい
- インドなどのマルチリンガルな国では端末自体は英語でセットアップされている事がある
- Voice usage
- イントネーションの違いなどによりうまく認識できないことが多い
- しかし、ラテン系以外の言語ではタイピングが難しいので、音声認識は良いUXを提供できる
- Errors
- 我々が当たり前と思っている概念が、新しい概念だと見なされる可能性がある
- 例えばゴミ箱アイコン=削除を示す、とはならない可能性があるよ
- エラーに関しては、ユーザーがどのようにすべきかのアクションを提示しようね
- 我々が当たり前と思っている概念が、新しい概念だと見なされる可能性がある
How to retain users with Android backup and restore
- 実際のユースケースを例に説明
- restore対応してないアプリは、新しいスマホに買い換えたときにアンインストールされる可能性がある、ということ
- ユーザーにとってrestoreを手動でやるのは難しい事である
- ログインすらもメアドやパスワードを忘れている可能性がある
- これは脅しのように聞こえるかも知れないが、Googleによるユーザーリサーチによるものだよ
- Android Backup and Restore
- iOS -> Android
- ケーブルで接続し、同等のアプリをGoogle Playから探してインストール出来る
- Android -> Android
- ケーブルで接続している場合、アプリごとに最大2GByteまでデータ転送が可能
- クラウド経由の場合、アプリごとに最大25MByteまでバックアップデータの復元が可能
- Android Backup and Restoreの利点
- アプリごとに再ログインが不要
- Googleアカウントで認証済みの場合
- デバイスごとの設定はnot同期にできる
- アプリごとに再ログインが不要
- iOS -> Android
- Configure B&R of your app
- Step 1: Meet Auto Backup
- 全てのアプリが拒否しない限りはデフォルトで有効
- Cache以外のほとんどは自動的にバックアップされる
- key/value で任意にバックアップも可能だよ
- 全てのアプリが拒否しない限りはデフォルトで有効
- Step 2: Can I costomize AutoBackup? Yes!
- どのファイル/フォルダをバックアップに含めるか選べるよ
- デバイスがE2Eの暗号化をサポートしている場合のみバックアップ、という事も可能
- Step 3: Transfer user credentials with BlockStore
- ログイン情報を転送できるよ
- Step 4: Test
- デバイス1つ or emulatorでできるよ
- インターネット接続もGoogleアカウントも不要
- クラウド経由 or ケーブ接続どちらもエミュレート可能だよ
- Step 5: Keep your implementation up-to-date
- 新しい機能を追加したときに、B&Rの実装に変更が必要となっていないかを検討してね
- Step 1: Meet Auto Backup
Best practices for making your app private by design
- Pay attention to data accesses
- AppOpsManagerを使って、いつ何にアクセスしているかが確認できるよ
- 専用のActivityで、なぜパーミッションが必要なのかを説明できるよ
- Respect user choice
- 求めるパーミッションが少ない方がユーザーがアプリを使ってくれる確率が高まるよ
- 将来的には通知を表示するにもユーザーの許可が必要となる予定だよ
- Minimize use of permissions
- Android11以上を対象に写真とビデオを追加パーミッション無しで選択できる機能を提供するよ
- サポートライブラリーの提供も予定しているよ
Reimagine animations system for a delightful development experience with Jetpack Compose
- 基本的なもの
- AnimatedVisibility
- AnimatedContent
- コンテンツ間のアニメーション用
- パラメーターはIntでも何でも良い
- General APIs
- animate*AsState
- single-value用
- updateTransition
- multiple-value用
- ラベルを付けておくと、Android StudioでPreviewするときに便利だよ
- animate*AsState
- Compose Animation Tools
- Animation Preview
- More Complex Scenarios
- Coroutine-based Animations
- suspend fun animate
- リスナーを使わなくてもシーケンシャルなアニメーションが実現しやすくなったよ
- パラレルに実行したい場合は、coroutineビルダーを複数回叩けば良いよ
- パラレルなアニメーションを待ち合わせたい場合、coroutineScopeを複数使えば良いよ
- Coroutine-based Animations
Make your build faster and more robust with the latest Android Gradle plugin
- KSP
- Non-transitive R classes
- Lint
- org.gradle.caching=true
- checkDependencies=true
- Configuration cache
- Build AnalyzerのOptimize thisをクリックして試すことができる
- gitのshaを使っているケースでの修正例の紹介
- Extending AGP
What’s new in Android Studio
- Recent Changes
- Bumblebee
- Material You
- Large Screen
- Jetpack Compose
- Animation Inspection
- Chipmunk
- Jetifierが必要かどうかのチェック機能を追加予定だよ
- Lintのキャッシュ
- Android11以上ではフレームのライフサイクルが見れる
- UIエディター
- カメラUIを画面の向きによってローテーションする例
- ConstraintSetを複数用意して、それの切替アニメーションをプレビュー可能
- Device Manager
- 色々な画面への対応
- Visual Linting
- ボタンが隠れている、画面が広いのにボトムバーを使っている、TextViewに多くの文字数を表示しすぎている、などを警告してくれる
- Visual Linting
- Bumblebee
- 開発中の機能
- Live editing
- Live literalをより一般化したもの
- ライトモード
- IDEが使用するリソースを減らすモード
- Live editing
Kotlin Flows in practice
- FlowのcollectをUI層でやるのは、repeatOnLifecycleが推奨の方法だよ
- repeatOnLifecycleのラムダの中で複数launchは可能だよ
What's new in Google Play
- Trust & safety
- Data safety section
- 2月からユーザーに見える&4月には対応必須
- レビューのために早めに提出をお勧めするよ
- Play Integrity API
- 下記のチェックが出来る
- 変更されていないバイナリか?
- Playからインストールされたから?
- Google Playサービスが実行されている本物のAndroidデバイスか?
- SafetyNetからのマイグレーション方法も公開予定だよ
- 下記のチェックが出来る
- Data safety section
- App quality
- Android vitals
- レーティングとレビュー
- 2021/11から、国ごとに表示されるよ
- Early 202から、デバイスごと(タブレットやChromebookなど)に表示されるよ
- すでにPlay Consoleからこれらをプレビューすることが可能だよ
- Reach and devices
- Monetization
- In-app messaging
- 購読の支払い失敗を通知できるよ
- 次にPlay Billing Libraryで一般公開される予定だよ
- 購読の支払い失敗を通知できるよ
- In-app messaging
- Games
- サインインがPlay Games Services SDKで簡略化できるよ
- Play Academy
Introducing Play Integrity API: Protect your apps and games (developer preview)
- 複数のAPIを提供していたが、一つにまとめたよ
- ただし、これは銀の弾丸ではないよ
What's new for large screens and foldables in Android and ChromeOS
- 大画面デバイスの利用は増えているよ
- そのため、大画面に適したAndorid12Lを開発している
- Jetpack
- WindowManager
- ウインドウのサイズはonCreateとonConfigurationChangedでWindowMetricsCalculatorを使って取得しましょう
- display APIは使わないで下さいね
- Testもサポートしているよ
- Activity Embedding
- XMLの定義を書くことで対応できるよ
- Rear Display Mode
- たとえばGalaxy Foldでunfold中のセルフィーを撮るのに使える
- ウインドウのサイズはonCreateとonConfigurationChangedでWindowMetricsCalculatorを使って取得しましょう
- Chrome OS
- AndroidアプリのP-in-Pモードを改良したよ
- より詳細な最適化の話は https://chromeos.dev/l/app_optimization を見てね
Build Android UIs for any screen size
- Build your app with adaptive UI
- Window size classes
- compact/medium/expanded
- これらをレイアウト切り替えのブレークポイントとして使えば良いよ
- Jetpack Windows Manager 1.1で対応予定だよ
- 基本的には幅だけを気にしてレイアウトを変更でOKなはず
- Reference Devices
- Bumblebeeに導入
- tablet/phone/foldable/desktop
- Bumblebeeに導入
- サンプルとしてJetNewsをチェックしてね
- Window size classes
- Trackrの例
- Visual Linting
- Reference Devicesを使えば、色々なデバイスでのレイアウト時に問題がありそうな箇所を解析できるよ
- Two Pane SlidingPaneLayout
- Surface Duoのような物理ヒンジのあるデバイスも考慮して表示出来るようになったよ
- Resizable Emulator
- 即座に各Reference Devicesのウインドウサイズに切替が出来るよ
- Visual Linting
- Side-by-side activities
- Two Pane SlidingPaneLayoutでもactivity embedding APIのサポートを検討しているよ
- Jetpack Compose
- JetNewsで対応した例の説明
- Foldableでfoldしたときにユーザーが最後に操作した画面を表示するため、custom modifierでコレを記録することにしたよ
- two-paneの場合は分かれているViewModelをどうするかの検討が必要だよ
- Nested nav graphにする / ViewModelを統合する などの選択肢があるよ
- Composableごとに例えば横幅でレイアウトを変えるには?BoxWithConstraintsが便利だよ
- ただし、通常のComposableと違ってサイズが確定するまでレイアウトが決まらないので、乱用しないように注意が必要だよ
- 表示する要素に変わりが無くレイアウトを変えたいだけなら、代わりにCustom Layoutの使用も検討してね
- JetNewsで対応した例の説明
- Testing
- 各フォームファクターごとのデバイスを全て保持するのは難しい
- Gradle Managed Devices
- テストを分割して複数のデバイスで実行することで、テスト時間の短縮も可能だよ
- テスト用に使用リソースを削減したATD(Automated Test Devices)を用意したよ
- Configuration changeのテスト
- 画面を回転させたり、Fold/Unfold/TableTopを切替できるようにするよ
Best practices for video apps on foldable devices
- Posture changes
- 例ではMotionLayoutで対応
- ReactiveGuide
- WindowManagerから取得した値から計算して、ReactiveGuideを移動
- 例ではMotionLayoutで対応
- Video streams
- 様々なアスペクト比への対応が必要
Design beautiful apps on foldables and large screens
- Column
- Window size classes
- Ergonomics and usability
- 例えばタブレットだと、上の方のUIは押しづらい
- Canonical layouts
- List Detail
- Supporting Panel
- Feed
- Responsiveなアプリ
- Navigation Graphは一つにするべき
- SlidingPaneLayoutを利用するなど
- RecyclerViewのLayoutManagerをWindows size classesによって切り替えるなど
- Navigation Graphは一つにするべき
- Test
- 各テストに独自のアノテーション(LargeScreenTestなど)をつけて、特定のデバイスで特定のテストだけ実行、という事も可能だよ
Create engagement and high quality playback on Android TV & Google TV
- The "Watch Next" Row
- Android TVでは "Play Next"
- Google TVでは "Continue watching"
- 途中まで再生したビデオを追加するかどうかは、ガイドラインにスレッショルドを提示しているよ
- どうやって実装するか?
- WatchNextProgram.Builder
- Guidelines
- 見終わったものは消してね
- トレーラとか短い動画を追加しないでね
- Quality Playback
- オーディオの優先順位はアプリが決める必要がある
- 今後のAndroidのアップデートで、Android自体がハンドリングできるようにする予定だよ
- リフレッシュレートの切替
- 一部のデバイスではスムーズに切り替えできない(1~2秒程度の黒画が発生)ケースがある
- この場合でも切り替える場合、事前にユーザーに知らせる事が推奨だよ
- 一部のデバイスではスムーズに切り替えできない(1~2秒程度の黒画が発生)ケースがある
- オーディオの優先順位はアプリが決める必要がある
- 古いバージョンのAndroidのサポート
- DisplayCompatを使えば4Kサポートしているか正確にわかるよ
- Android12より前の場合、ディスプレイが変わる=STBは再起動をお勧めだよ
- ExoPlayer
- 適切なストリームが選択されない場合、TrackSelectorをカスタマイズしてね
- コンテンツに必要なHDCPプロテクションレベルは考慮されていないので、TrackSelectorをカスタムかサーバーサイドで対処してね
- non-seamlessなリフレッシュレート変更を使う場合、seamlessなリフレッシュレート変更を無効にしてね
- 2.15からデコードとレンダーは同じスレッドでおこなうようになったよ
- 一部のデバイスではデコードが遅くて表示がカクつく事もあるので、その時はMediaCodecRendererの実験的フラグをONにして、別スレッドでおこなう事も出来るよ
- ただ、スレッドの競合問題が起きる可能性があるので注意してね
- 一部のデバイスではデコードが遅くて表示がカクつく事もあるので、その時はMediaCodecRendererの実験的フラグをONにして、別スレッドでおこなう事も出来るよ
What's next for AndroidX Media and ExoPlayer
- 典型的なアプリの場合
- Androidや他のアプリは、ビデオやオーディオが再生中かどうか知ることが難しいので、ユーザーが再生をコントロールできる便利な方法が提供できないよ
- Media sessionと接続することで、何を再生しているかの情報提供や再生のコントロールを連携できるよ
- これにより、Android11のMedia controls/Wear OS/Google Assistant/Media key eventsなどでの制御が可能となるよ
- ただし、実現するのは大変
- androidx.media2とexoplayerがあるけど、色々なapiやmoduleが重複しているよ
- Media3では、これらを統合するよ
- ExoPlayerのinterfaceを標準化し、MediaSessionやUIでこれを使うようにするよ
- Media sessionと接続することで、何を再生しているかの情報提供や再生のコントロールを連携できるよ
- Androidや他のアプリは、ビデオやオーディオが再生中かどうか知ることが難しいので、ユーザーが再生をコントロールできる便利な方法が提供できないよ
- これまでにやってきたこと
- Player interface
- MediaItem
- 何を再生するかを指示するための使いやすいAPI
- 簡単なケースではURLを渡すだけだが、DRM再生などにも対応できるよ
- Playlists
- addMediaItemするだけ
- Error codes
- Structured MediaMetadata
- Available commands
- Track selection
- onEvent callback
- などなど
- MediaItem
- Audio
- オーディオフォーカスを自動で処理できる
- 他アプリが再生中なら、これをフェードアウトできる
- 再生するデバイスが切り替わったら、ノイズ発生防止のために再生を一時停止
- WakeLockの制御も可能
- オーディオフォーカスを自動で処理できる
- Player interface
- Working with other apps
- MediaSessionService
- 再生停止などのコントロールを外部からできるように
- BTヘッドセットやAndroid OSの通知から制御が可能となるよ
- 再生停止などのコントロールを外部からできるように
- MediaLibraryService
- コンテンツを外部から使えるように
- Android Auto側に安全にコンテンツを表示出来るよ
- playback resumptionもできるようになるよ
- Android11以降の新機能で、音楽の再生を途中から再開できるよ
- コンテンツを外部から使えるように
- MediaSessionService
- Media3 versioning
- Stable API
- ExoPlayerのAPIをstableとunstableに分けるよ
- stable
- 基本的なPlayer/MediaItem/Media sessionsな
- unstable
- カスタム出来るインターフェースや、MediaSource
- Media3で使用するには、op tinが必要だよ
- 徐々にstableを増やしていく予定だよ
- stable
- ExoPlayerのAPIをstableとunstableに分けるよ
- Stable API
- Media3 for ExoPlayer users
- ExoPlayerとMedia3の両方のリリースを1クォーターおこなう予定だよ
- Media3もGitHubに公開予定だよ
Design to code: Turning handoffs into high-fives
- デバイスが多様化しておりデザインして実装するのがより大変になってきている
- デザイナーとAndroid開発者のやりとりが大変
- Figmaと提携しているよ
- 新しいワークフローではFigmaでデザインしたUIをComposeとして取り込めるよ
- Figma上でText/Image/Iconを動的なものとしてマークすることで、Composableの引数として渡せるようになるよ
- どのユーザー操作(onClickなど)が可能かをFigmaで示す事で、Composableの引数にラムダとして渡せるようになるよ
- デザインの変更も容易に取り込めるよ
- コードのように管理されており、Updateするだけで最新のものを取り込めるよ
- モジュラー化されており拡張も可能なので、開発者は必要な箇所だけオーバーライドも可能だよ
- アーリーアクセスプログラムに興味がある場合はこちらから登録を
Preparing your app for the new Data safety section in Google Play
- アプリが収集するデータに関してユーザーの関心が高いよ
- あるユーザーからのフィードバック
- 「データを提供しない場合、どの程度アプリの機能が使えなくなるのかが知りたい。これは、データを提供するかどうかの判断の助けになるため」
- あるユーザーからのフィードバック
- Data safety section
- 大きく二つのカテゴリ
- Shared data, Collected data
- 大きく二つのカテゴリ
- Privacy updates
- プライベートポリシーとData safety sectionの一貫性に気をつけてね
- プライベートポリシーはPlay Consoleへの登録と、アプリへの掲載が必須になったよ
- プライベートポリシーにどのようなデータにアクセスして収集、使用しているか掲載が必要だよ
- 詳しくは g.co/play/userdata を参照してね
- Apps targeting children
- ターゲットに子供が含まれるアプリでは、GooglePlayファミリーポリシーに準拠が必須だよ
- 例えば、広告SDKは認証されたものだけが利用可能だよ
- ユーザーが子供かもしくは年齢が不明の場合、IMEIなどのIDは送信不可だよ
- ユーザーが子供かもしくは年齢が不明の場合、2022/4/1からAndroid Advertising ID(AAID)も送信はNGだよ
- 詳しくは g.co/play/familiesdatapractices を参照してね
- ターゲットに子供が含まれるアプリでは、GooglePlayファミリーポリシーに準拠が必須だよ
Jetpack Compose with Material You #AskAndroid
- アニメーションに関して
- まだstableではないAPIがある
- shared transitionについては取り組んでいるところ
- たとえばLottieはComposeでほぼ動くようになったと聞いている
- もし、今のAPIで実現できないアニメーションがあれば、ぜひ教えて欲しい
- MotionLayoutにかなり依存している場合
- 機能的なギャップは大きくないと思う
- MotionLayoutはViewシステムで快適なアニメーションを実現するため、生まれたもの
- しかし、Jetpack Composeは最初からアニメーションを考慮している
- ブランドカラーとMaterial You
- ダイナミックカラーでブランドカラーとマップする配色のカラースロットを指定することは可能だよ
- Scaffoldはナビゲーションの外と中、どちらに置くべき?
- ちょうど、チームで議論しているところ
- JetNewsで大画面対応するに当たり、Scaffoldのネストも発生した
- 理想的ではないが、現状はJetNewsを参考にしてもらうのが良いよ
- ちょうど、チームで議論しているところ
- elevation
- 影ではなく色のトーンで表現するようになったよ
- 例としてAndroid12のSystemUIがあるよ
- Jetpack Composeでのスナップショットテスト
- 内部で取り組んでいるところだよ
- FacebookのSnapというライブラリはあるよ
- RecyclerViewのLayoutManagerのようなものは将来的に導入されますか?
- これも取り組んでいる最中だよ
- Composeでのキーボードのサポートについて
- 1.1でかなり改善しているので、試して見てね
- ColorなどをKotlinファイルで定義する場合、まだTheme.xmlは必要ですか?
- Manifestで使用するファイルなどは、Theme.xmlが必要です
- ViewとComposeの両方がある場合、色などはXMLを唯一の情報源とする事が推奨です
- ComposeでAndroidTVアプリを作り時に気をつける事はありますか?
- 1.0ではphone向けに注力していたが、1.1では大画面に注力しているよ
- まだ自チームではTVに取り組んではいない
- 完璧ではないが、D-Padナビゲーションをサポートしたよ
- TV向けは事前に充分なテストを推奨するよ
Developing for large screens #AskAndroid
- エンジニアは大画面にどのように最適化を考える必要がありますか?
- フォルダブルではマルチタスキングの利用が7倍になっている
- WindowClassによるレイアウト切り替えのサポート
- ナビゲーションUIの切替も推奨
- フォルダブルで重要な事の一つは、fold/unfoldでアプリの体験を継続することだよ
- 最も簡単に色々なスクリーンに対応する方法は何でしょう?
- アプリの現状と将来の計画に依存する
- Activity embedding
- Composeによるサイズ変更が容易なレイアウト
- 互換性モードはあるが、これは理想的な体験を提供できないので、できれば避けるべき
- WindowClassについて
- グリッドやカラムの数、マージンの値の決定などをWindowClassでわける必要は無いよ