Android Kotlin基礎講座 05.1: ViewModelとViewModelProvider
目次
タスク:スターターアプリの問題点を見つける
このタスクではスターターアプリであるGuessTheWordアプリに含まれる問題点を見つけていきます。
- スターターコードを起動して、SkipボタンやGot itボタンをタップしてゲームをプレイしてみてください。
- ゲーム画面には現在、単語と得点が表示されています。実機や端末を回転させて画面の向きを変えてください。現在の得点がなくなることを確認してください。
- 更に単語を表示させてゲームをプレイしてください。ゲーム画面にある程度得点が表示されたら、アプリを閉じてもう一度開いてください。ゲーム結果が最初からリスタートされていることを確認してください。これはゲームの状態がセーブされていないためです。
- さらに単語を表示させてゲームをプレイしてください。End Gameボタンを押して、何も起こらないことを確認してください。
アプリの問題点:
- スターターアプリは画面の向きが変わったことなどによるコンフィグレーション変化や、アプリがシャットダウ
onSaveInstanceState()コールバックを使ってこの問題を解決することができます。しかしonSaveInstanceState()メソッドは使うにはbundleにデータを保存するためのコード、さらにデータを復元するためのロジックを実装しなければなりません。また保存できるデータ量は最小限になってしまいます。 - ゲーム画面でEnd Gameボタンを押しても得点画面に遷移しません。
これらの問題はこの記事で学習するアプリアーキテクチャコンポーネントを利用することで解決できます。
アプリアーキテクチャ
アプリアーキテクチャはアプリのクラスやクラス間の関係をデザインするための方法の一つで、これによりコードをきれいにし、特定の状況下で効率よく処理させたり、簡単に動作させることができます。レッスン5の4つの記事を通してGuessTheWordアプリに加えていく改良はAndroidアプリアーキテクチャガイドラインに従って、Androidアーキテクチャコンポーネントを使用していきます。AndroidアプリアーキテクチャはMVVM(model-view-viewmodel)パターンによく似ています。
GuessTheWordアプリは関心の分離デザイン原理に従い、それぞれのクラスが分離された役割を果たすように分割されています。レッスン5の初回であるこの記事で作業していくクラスはUI conrtoller、ViewModel、ViewModelFactoryです。
UI controller
UI controllerはActivityやFragmentのようなUIベースのクラスです。UI controllerにはビューやユーザーインプットを捕捉するようなUIや対話OSを操作するロジックのみが含まれるべきです。テキストを表示するためのロジックのような意思決定論理はUI controllerの中には入れてはいけません。
GuessTheWordスターターコードでは、UI controllerはGameFragment、ScoreFragment、TitleFragmentの三つのフラグメントです。『関心の分離』デザイン原理に従い、GameFragmentはゲームの要素を画面に描写することとユーザーがボタンをタップしたことを知る役割だけを担っています。それ以外は何もしません。
ユーザーがボタンをタップしたとき、タップしたという情報がGameViewModelに渡されます。
ViewModel
ViewModelはViewModelに関連するフラグメントやアクティビティに表示されているデータを保持します。ViewModelはUI controllerによって表示されるデータを準備するための単純な計算やデータの変換などを行います。このアーキテクチャでは、ViewModelが意思決定を行います。
GameViewModelは得点の値や単語のリスト、現在の単語といったデータを保持します。なぜならこれらは画面に表示されるデータだからです。また、GameViewModelにはデータの現在の状態が何なのかを決定するための単純な計算をするためのビジネスロジックも含まれます。
ViewModelFactory
ViewModelFactoryはViewModelオブジェクトをインスタンス化します。
後の記事でUI conrtollerやViewModelに関連するほかのAndroidアーキテクチャコンポーネントについて学習します。