クラウドエンジニアのノート

情報技術系全般,自分用メモを公開してます。

Android MVVM

はじめに

qiita.com こちらの記事をベースにMVVMについて学習したので,その備忘録です.

MVVM

フォルダ階層

.
├── service
│   ├── model
│   │   ├── Project.java
│   │   └── User.java
│   └── repository
│       ├── GithubService.java
│       └── ProjectRepository.java
├── view
│   └── ui
│       └── MainActivity.java
└── viewmodel
    └── ProjectListViewModel.java

model

  • UIに関係ない処理を行う場所
  • repositoryはviewModelに対するデータプロバイダ(API叩くソースを書くところ)
  • viewModelから呼び出され,コルーチン(非同期)でサーバからデータを取得
    • [コルーチン]関数呼び出しを途中で中断できるが,スタック領域に残っており,もう一度呼ぶとその中断したところから再開できる

MVVMSamleで使ったkotlin文法

  • companion Kotlin では、class 定義の中で object を宣言するとき、companion というキーワードをつけることができる。このキーワードがついた object をコンパニオンオブジェクトと呼ぶ.コンパニオンオブジェクトのメンバは クラス名.メンバ名 でアクセスできる.
    • つまりjavaのstaticの代わり
    • companion object の後ろの {} の中は、通常のクラスの本体と同じように実装
    • companion object Factory のように名前付けられるけど,Book.Factory.FREE_PRICEでもBook.FREE_PRICEでもどっちでもアクセス可能
    • しかも,クラスの中でcompanion objectは1つしかだめだから,名前つける意味ないかもね

companion補足

data class Book(val title: String, val price: Int) {
    companion object {
        const val FREE_PRICE = 0
        fun newFreeBook(title: String) = Book(title, FREE_PRICE)
    }
}

fun main() {
    val book = Book.newFreeBook("Free Kotlin")
    println(book)  //=> Book(title=Free Kotlin, price=0)
}

MutableLiveData vs ObservableFiel

両方ともDataBindingに使えるオブジェクト

  • MutableLiveData<>()

    • ActivityやFragmentのライフサイクルに応じて、ほぼ自動で購読管理をしてくれる。
    • 意図しないクラッシュ防ぐことができる
    • DataBindingできる
  • ObservableField<>()

    • DataBindingをするときに使う。
    • ライフサイクルには対応しておらず、購読管理を自動ですることはできない

MutableLiveDataを使いましょう

Application

  • viewModelからリソースにアクセスしたりできる
  • viewModelProvidersで初期化するにはViewModelかAndroidViewModelを継承する必要がある
  • この方法で初期化したViewModelは画面回転時も値を引き継ぐことができる
  • ViewModelProviders.of()で渡すものによってViewModelのスコープが決定
    • Activityを渡せばそのActivityで使えますし、Fragmentと同じ
    • Fragmentで親Activityのインスタンスを渡せばActivity内のスコープとなるため、ActivityとFragmentで同じViewModelを操作することができる
    • コールバック付けなくても,データ共有できるみたい
class ProjectViewModel(private val myApplication: Application, private val mProjectID: String) :
    AndroidViewModel(myApplication)