Android 12(API 31)までは、onActivityResult
→ onStart
の順序でしたが
Android 12L(API 32)からは、onStart
→ onActivityResult
の順序に変わっています
※ActivityResultContract
を使っていても影響を受けます。ActivityResultContract
のコールバックはComponentActivity
のonActivityResult
の中でコールされるためです。
その順序が変わっても問題が起こるようなことはなかろうなどと思っていたら、問題にぶち当たりました(単に使い方が悪かっただけではありますが)
以下のように、onActivityResult
(実際にはActivityResultContract
のコールバック)で、LiveDataの値を2回更新するようなことをしていました。
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
viewModel.liveData.value = 1
viewModel.liveData.value = 2
}
そして、このLiveDataをObserveしているとしましょう。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.liveData.observe(this) {
// hogehoge
}
}
各ライフサイクルイベントなどにログを仕込んで実行してみます
Android 12(API 31)まで
onCreate
onStart
onResume
startActivityForResult
onPause
onStop
onActivityResult
onStart
liveData: 2
onResume
Android 12L(API 32)から
onCreate
onStart
onResume
startActivityForResult
onPause
onStop
onStart
onActivityResult
liveData: 1
liveData: 2
onResume
LiveDataのObserverがActiveになり、値を受け取るれるようになるのはonStart
以降なのです。
Android 12L(API 32)以降の場合、onStart
→ onActivityResult
なので、onActivityResult
がコールされた時点で、ObserverがActiveになっているため、2回の更新どちらの値も受け取ることができます。
ところが、Android 12(API 31)までは、onActivityResult
→ onStart
なのでonActivityResult
がコールされた時点で、ObserverがActiveになっていません。その後のonStartでActiveになります。そのため、最終的な値を1回のみ受け取るという違いが出てしまいます。
LiveDataをすべての値の更新を受け取れる前提で使うこと自体、良くない実装です。
ただ、このライフサイクルの違いは、開発に使用している端末が最新のOSだった場合、開発中には気づくことができず、下流工程で問題が見つかる。なんてことになったりするので注意しましょう。