MVVM 完全に理解した - 2
今回は ViewModel について。
ViewModel とは
The ViewModel class allows data to survive configuration changes such as screen rotations.
Activity が破棄・再生成される画面回転などの操作について、(UI と関連した)データをロストさせないようにできるクラスとのこと。
ViewModel クラスのメソッド
public abstract class ViewModel { protected void onCleared() { } }
onCleared
のみが定義されています。
詳しくは後述。
実装例
リファレンスの実装例を見てみます。
class MyViewModel : ViewModel() { // LiveData を保持 private lateinit var users: MutableLiveData<List<User>> //LiveData を取得 fun getUsers(): LiveData<List<User>> { ... } ... }
Activity からアクセスするときは次の通り。
class MyActivity : AppCompatActivity() { override fun onCreate( ... ) { //MyViewModel の生成 val model = ViewModelProviders.of(this).get(MyViewModel::class.java) //LiveData#observe model.getUsers().observe(this, Observer<List<User>> { users -> // UI のアップデート処理を記述 // users is List<User> }) } }
Create a ViewModel the first time the system calls an activity's onCreate() method
Activity#onCreate メソッドが呼ばれるときに ViewModel を生成しなさいよ~とのこと。
ここで、
ViewModel は view や Lifecycle, または Activity context への参照を保持しているクラスを "絶対に" 参照するなよ!!
との注意書きが…!
ViewModel オブジェクトは、View や LifecycleOwners ( Activity や Fragment ) などのインスタンスよりも長生きするように設計されている
すなわち、ViewModel 内でこれら寿命が短いインスタンスを参照すると、メモリリークする可能性が出てきます。参照だめ絶対。
一方で、この構造は View や Lifecycle オブジェクトを知らないくても容易にテストが可能であることを示します。
もし、システムサービスなどのために Application context が必要な場合は、AndroidViewModel
を拡張して使うことができます。
AndroidViewModel
はコンストラクタで Application
を受け取るためです。
(これ Toast や Snackbar の操作に使えそう)
AndoridViewModel (Application application)
さて、さっきちらっと出てきた onCleared
ですが、これどこで呼ばれるのかというとActivity#onDestroy 後のほんとに最後だそうです。
画面回転で onDestroy
呼ばれても死にません。 Activity#finish() が呼ばれた後にコールされるようです。
まとめ
公式リファレンスでも、ViewModel は LiveData と一緒に使うのが前提みたいになってますね。
次は DataBinding について。