気になるのはライフサイクル。
きっかけ
フル Compose でよくあるTodoのようなメモのようなアプリを作ってみました。
一通りの機能は実装しました。
👉 Jetpack Compose without ViewModel #shorts - YouTube
いろいろ Compose を試しながら進んでいくと ViewModel がスカスカになりました。
@HiltViewModel
class TodoViewModel @Inject constructor(
private val repository: TodoRepositoryInterface
) : ViewModel() {
val items: Flow<List<Todo>> = repository.load()
fun insert(text: String) = repository.insert(text)
fun update(id: Long, text: String) = repository.update(id, text)
fun delete(id: Long) = repository.delete(id)
}
ViewModel いらなくね?
ViewModel を省略して、Repository を直結します。
結果
以下、少しの書き換えで問題なく動きます。
@Composable
fun TodoScreen(
//viewModel: TodoViewModel = hiltViewModel()
repository: TodoRepository = TodoRepository(
Database(
AndroidSqliteDriver(
schema = Database.Schema,
context = LocalContext.current,
name = "database.db"
)
)
)
) {
//val items by viewModel.items.collectAsState(initial = emptyList())
val items by repository.load().collectAsState(initial = emptyList())
//viewModel.insert(target.text)
repository.insert(target.text)
//viewModel.update(target.id, target.text)
repository.update(target.id, target.text)
//viewModel.delete(target.id)
repository.delete(target.id)
//viewModel.delete(target.id)
repository.delete(target.id)
画面回転問題なし、メモリーリークもありません。
すんなりです。
Square製 SQLDelight + Flow(coroutine extension) を使っていますが、
Room + LiveData でもいけると思います。
Composable で Flow(LiveData) を受け取った瞬間に、
collectAsState(ObserveAsState) で State
それのほうが良くね?
ライフサイクルの差も気にしなくていいし。
しかし、緩衝国がなくなるのはなんだか不安です。
Hilt で @Singleton で、ぶち込んでやりたかったです。
あ、でもこれ、 re-compose のたびに、Repository インスタンスが...
👉 「SwiftUIでMVVMを採用するのは止めよう」と思い至った理由 - Qiita
👉 ViewModel はいつ生まれていつ死ぬか 【→ Jetpack Compose】
👉 Jetpack ComposeとViewModelについて考える - Blog - Mori Atsushi