branch10480’s blog

Topics that I've learned.

Andriod の ViewModel について 〜 1 〜

ViewModel の概要

ViewModelはライフサイクルを意識し、UI関連のデータの保存・管理用のクラスです。

UIコントローラ(アクティビティやフラグメント)の主な目的は、UIデータの表示、ユーザー操作への対処、OSとのやり取り(権限リクエストなど)を行うことです。

それ以外のデータベースやネットワークからのデータ読み込みなどの責務は別のクラスに移したほうがファイルの肥大化を防げ、テストもしやすくなります。

ViewModelを実装する

アーキテクチャコンポーネントにはUIコントローラ向けにUIのデータを準備する ViewModel ヘルパークラスが実装されています。

ViewModel オブジェクトは設定の変更時に自動的に保存され、このオブジェクトが保持しているデータはUIコントローラが復帰時に即座に利用できます。

class MyViewModel : ViewModel() {
    private val users: MutableLiveData<List<User>> by lazy {
        MutableLiveData().also {
            loadUsers()
        }
    }

    fun getUsers(): LiveData<List<User>> {
        return users
    }

    private fun loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}

このように用意した ViewModel はアクティビティから以下のようにして利用できます。

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        // Use the 'by viewModels()' Kotlin property delegate
        // from the activity-ktx artifact
        val model: MyViewModel by viewModels()
        model.getUsers().observe(this, Observer<List<User>>{ users ->
            // update UI
        })
    }
}

オーナーであるUIコントローラが終了すると、フレームワークはリソースクリーンアップのため、ViewModel オブジェクトの onCleared() メソッドを呼び出します。

注意!

ViewModel には LifecycleObserversLiveData オブジェクトなど)を含めることができます。

ただし、ViewModel では、以下への参照が保持されている可能性があるクラスは参照してはいけません

  • View
  • Lifecycle
  • アクティビティコンテキスト

ViewModelApplication のコンテキストが必要な場合(システムサービスを検出する場合)は AndroidViewModel クラスを拡張して Application を受け取るコンストラクタを作成できます。(Application クラスは Context を拡張したもの)

ViewModel のライフサイクル

回転を行ってから終了するまでのアクティビティのライフサイクル、及び ViewModel のライフタイムは以下のようになります。

ViewModelのライフサイクル

通常、アクティビティオブジェクトの onCreate() メソッドが最初に呼び出された時に ViewModel をリクエストします。

ViewModel は最初にリクエストしてからアクティビティが終了して破棄されるまで存在し続けます。

参考

ViewModel の概要