blogこの広告は、90日以上更新していないブログに表示しています。サンプルコードや図を全て写していないので、原文を見ながら適宜理解を深めるのに利用してください。理解しやすいよう所々補足を加えています。先にアクティビティの実行時の変更処理について理解しておくと読みやすくなります。ViewModelViewModelクラスはUIに関連するデータの保持と管理をするようデザインされています。そのため画面回転などの設定変更があってもデータは保持されます。アクティビティやフラグメントなどのAppコンポーネントはAndroidフレームワークによって管理されるライフサイクルを持ちます。Androidフレームワークは、開発者がコントロールできないユーザーのアクションや端末のイベントに従って、ActivityやFragmentを破棄または再生成するか決めます。Activity/FragmentのオブジェクトがOSによって破棄または再生成されると、それらが保持していた全てのデータは破棄されます。ユーザーのリスト(List<User>)をActivityが持っていて、設定変更によってActivityが再生成されると、新しく生成されたActivityはリストデータを取得し直さなければなりません。データが単純ならActivity#onSaveInstanceState()メソッドを使って、Activity#onCreate()でBundleからデータを修復することができます。この方法は、UIの状態など少量のデータに向いています。サイズが大きくなりそうなユーザーのリスト(List<User>)には向いていません。他にも問題があります。activityやfragmentなどのUIコントローラーは戻るまでに時間のかかる非同期の処理を頻繁に呼ぶ必要があります。UIコントローラーはそれらの非同期処理を管理する必要があります。非同期処理が中断されたら、メモリリークを避けるためそれらを片付ける必要があります。これは多くの管理を必要とします。オブジェクトが設定変更によって再生成されて、同じ処理が呼ばれることはリソースの無駄使いです。最後にこれも重要なことですが、これらのUIコントローラーはユーザーのアクションに反応したり、OSとのコミュニケーションに対応する必要があります。自身が持つリソースも管理することになると、クラスは膨れ上がります。そのような状態は、1つのクラスがアプリのすべての機能を他のクラスに委譲せずに自分自身でやろうとすることになります。このような状態はテストを難しくします。Viewに必要なデータのオーナーシップをUIコントローラーのロジックから分離するのが簡単で効果的です。ライフサイクルパッケージはViewModelと呼ばれる新しいクラスを提供します。これはUIコントローラー(Activity/Fragment)のためのヘルパークラスで、UIに使うデータを準備する役割を担います。ViewModelは設定変更があっても自動的に保持されます。そのため、ViewModelが持つデータは再生成されたActivity/Fragmentですぐに利用できます。前述しましたが、ユーザーのリスト(List<User>)を取得し保持するのはActivityやFragmentではなく、ViewModelの責任であるべきです。Activityが再生成されても、再生成された新しいActivityは、前のActivityによって作られたものと同じViewModelのインスタンスを受け取ります。Activityが破棄されると、AndroidフレームワークはViewModel#onCleared()を呼び、ViewModelのインスタンスは破棄されます。Activity/Fragmentの初期化時にもViewModelは生き残ることから、ViewModelはViewを参照するべきではありません。どんなクラスでもそれがActivityコンテクストの参照を持つ場合は、そのクラスを参照すべきではありません。ViewModelがApplicationコンテクストを必要とする場合は、提供されているAndroidViewModelを継承して、コンストラクタでApplicationを受け取ってください。Fragments2つ以上のフラグメントが1つのアクティビティの中で、連携を取り合うことはよくあることです。2つのフラグメントがインタフェースを定義し、オーナーであるactivityが2つを結ぶことは、珍しいことではありません。2つのフラグメントはお互いが存在するか、visibleな状態であるか考えなければなりません。このよくある問題は、ViewModelオブジェクトを使って解決できます。fragmentsのケースを想像してください。アイテムリストを表示するfragmentからユーザーがアイテムを1つ選ぶと、選んだアイテムの詳細を表示するfragmentが出てくるパターンです。この2つのfragmentは、Activityのスコープを使って、お互いのコミュニケーションを管理するためにViewModelを共有することができます。gistbd67d578044e830ee00943b0e43145e72つのfragmentがVIewModelProviderを利用する際、getActivity()を使っていることに注意してください。これは2つのFragmentが同じactivityの範囲で、SharedViewModelのインスタンスを受け取ることを意味します。このアプローチの利点:Activityは何もする必要がありません。fragmentsのコミュニケーションについて知る必要もありません。FragmentはViewModel以外、お互いを一切知る必要がありません。片方が消えても、もう片方はいつも通り動き続けます。各Fragmentはそれぞれのライフサイクルを持ちます。片方のライフサイクルの影響を受けることもありません。実際、Fragmentが他のFragmentに入れ替わっている間も、UIは問題なく機能します。ViewModelの機能は、ViewModelを取得する際ViewModelProviderに渡したライフサイクルの範囲で利用できます。(activityを渡したら、activityがfinish()されるまで利用できます。)ViewModelは、ライフサイクルが終了するまでメモリに置かれます。activityならActivity#finish()、fragmentならFragment#detached()が呼ばれるまで、メモリに残ります。SavedInstanceStateViewModelは、設定変更があってもデータを保ち続けるための簡単な方法を提供します。アプリケーションがOSによってkillされるときは破棄されます。OSが保存されたデータからActivityを復元しています。state機能を使って状態を保存します。ほとんどの場合、開発者は何もする必要がありません。開発者はonSavedInstanceStateコールバックを使ってデータをbundleに追加するだけです。onSavedInstanceStateを使って保存されたデータは、システムのプロセスメモリに保持されます。OSは開発者にとても少ない量のデータを保持することを許可しています。そのため、実際のデータ(アプリが使うコンテンツデータ等)を保持させるのに適した場所ではありません。開発者は、UIコンポーネントによって簡単に置き換えられないデータのためにプロセスメモリを使うのは控えましょう。stateに入れないでください。countryIdを入れることはできます。実際に利用するオブジェクトはデータベースに入るべきです。ViewModelが保存されたcountryIdを使って、オブジェクトを取得します。ViewModelTweet広告を非表示にする関連記事2017-03-05BitcoinのBlockとTransactionのデータ構造についてBitcoinはP2P通信技術を利用している。Android.月別アーカイブ参加グループプログラミングはてなブログをはじめよう!bambinyaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。