はじめに
AndroidTV(ATV)アプリ開発はAndroidアプリ開発とは考え方が異なる点が多く、開発を難しくしています。
そこで本記事はATV開発での開発の方針を取り上げ、ATV開発の難易度を下げることを目的としています。
本記事の対象読者はAndroidアプリを開発したことがあり、ATVアプリを開発しようと考えている開発者を想定しています。
ATV端末について
さっそくですが、端末について考察していきましょう。
ATV端末はかなりの数があり、特徴も様々なものがあるため筆者が開発経験したことがある端末の中で特徴的なものを下記表にまとめました。
端末名 | コメント | 備考 |
---|---|---|
CCC Air Stick 4k スタンダード版 | バッググラウンドからフォアグラウンドの実験が簡単に試しやすく、端末内の処理系も平均的に低い方のため開発用端末として適しています。 | 筆者のお気に入り端末です。 |
popIn Aladdin | 縦横に対するdpが標準ではなく、AndroidStudioのプレビューより各Viewパーツが実際には小さく表示されます。popIn Aladdinに対するレイアウトの対策は後ほど取り上げます。 | popIn Aladdin独自のストアになります。 |
FireTV | ATV端末として扱って良いかは微妙ラインですが、開発に関しては一部機能を除いてATVと同じように作って問題ないです。 | FireTV独自のストアになります。 |
Chromecast with Google TV | 標準機能が搭載されている上にCast機能があります。似たような端末でNexus Playerなどがあります。 | |
FireTV Stick AFTTモデル | 機能自体は他FireTVと同じですが、このモデルはスペックがかなり低いためパフォーマンスチェックに非常に向いている端末となります。 | FireTV独自のストアになります。 |
値段・入手のしやすさを考慮すると開発端末としてはFireTVが良いかと思います。
FireTV端末とATV端末
実装においてFireTV端末とATV端末に差はほとんどないですが、課金機能や音声認識機能などの一部機能では差があり、ATV端末とFireTV端末で同じ実装で作るとどちらかの端末でクラッシュする可能性があります。
そこでFireTV端末とATV端末の両方をサポートするアプリを開発する場合はBuildVariantを使用して各プラットフォーム特有の機能を呼び出す実装が切り替わるようにすると上手くいきます。ストアが分かれているため、処理の切り分けはFireTV用とATV用のapkを2つ用意することにより実現可能です。
popIn Aladdin
基本的にはATV端末と同じように作って問題ないのですが、レイアウトがイメージ通りに行かないことが多々起こります。実装でのコツはConstraintLayoutでしっかり組むことです。GuideLineを正しく使うことでレイアウトが崩壊することがほぼなくなります。
ストアが分かれているため、popIn Aladdin用に作るのも一つの手です。
設計方針
ATVアプリ開発を難しくさせている一番の原因がAndroidアプリ開発における設計の考え方が大きく異なる点です。簡単に実装するためのコツは「Andoridアプリの操作感を忘れよう」です。
フォーカスとバックキーアクション
ATVの設計を上手にやるコツとしてフォーカスに注目する手があります。
Androidでのフォーカスをもらえる条件はそのViewが画面内に存在することが大半を占めます。一方ATVでは、現在フォーカスを持っているViewに隣接していることが条件であることがかなり多いです。つまりこれは下図のようなフォーカス可能エリアになります。

これがAndroidと大きく異なる点です。そしてこの「フォーカス」について更に言及していくとバックキーアクションに関してもAndroidアプリ開発とは異なる設計を取らないといけなくなります。
Androidでのバックキーアクションの大半はActivityの終了やタブの切り替えが多くを占めますが、ATVではそれらに加えて「現在フォーカスしているViewから以前フォーカスしていたViewにフォーカスを移す」というアクションを持つことがあります。このアクションは横並びのシェルフ、縦並びのリスト表示やタブメニューとコンテンツ画面の関係などでよく出てくるパターンで縦並びのリスト表示を一例にするとindex99のView(一番上以外のView)に現在フォーカスが当たっている時にバックキーアクションを起こした時にindex0(一番上のView)にフォーカスが移動するようなアクション設定がよくされます。
このようにバックキーアクションの設定がフォーカスと密になってくる点が設計を狂わせてくる要因になります。
フォーカスに対する解決策
フォーカス制御に対するアプローチ手段は主に3つあります。
1: Viewクラスに対するsetOnKeyListener
2: レイアウトファイル内のnextFocus
3: leanbackのBrowseFrameLayout
基本的に使うと良いのがBrowseFrameLayoutですが、ScrollViewが絡んだりすると正しく動かなくなったりします。その時にsetOnKeyListenerなどで回避すると綺麗にまとまるかと思います。
また、Presenterパターンに切り出すなどしてあげて、フォーカスについての関心分離を適切に行うことでAndroidアプリ開発に帰着し、ATVアプリ開発の敷居を大きく下げることができます。
バックキーアクション設定実装の罠
バックキーアクション設定はATVにおいて難易度が高くなる傾向があります。これはAndroidアプリでは画面が小さいためOneActivity内における機能数はATVより少なくシンプルにまとまるケースが大半ですが、逆にATVは画面が大きいことに注目され、OneActivity内の機能数が多くなり、結果的に処理されるFragmentが多くなります。
ATVアプリ開発で何も考えずにFragment内で requireActivity().onBackPressedDispatcher
を多用すると互いに干渉しあい正常に動作が行われません。
Fragmentやライフサイクルを適切に扱い、画面構成を早い段階で整理し、バックキーアクションの設定手法はどの実装が適切かを判断することで事故を回避しやすくなります。
まとめ
ATVアプリ開発はAndroidアプリ開発と異なる点をしっかり洗い出し、適切に関心分離をしAndroidアプリ開発の手法に近づけていくことが成功の鍵になりやすいです。
興味を持っていただけましたらATVアプリ開発を一度でも良いのでtryしてみてください。
ATVアプリ開発に興味がある方が多そうでしたら、実装についてもっと踏み込んだ記事を展開しようと思いますのでTwitterなどでのご感想・ご指摘などお待ちしております。