LoginSignup
32
9

More than 1 year has passed since last update.

API 31までとAPI 32からは、onStartとonActivityResultの実行順序が逆になっている件

Last updated at Posted at 2023-02-16

Android 12(API 31)までは、onActivityResultonStart の順序でしたが
Android 12L(API 32)からは、onStartonActivityResult の順序に変わっています

ActivityResultContractを使っていても影響を受けます。ActivityResultContractのコールバックはComponentActivityonActivityResultの中でコールされるためです。

その順序が変わっても問題が起こるようなことはなかろうなどと思っていたら、問題にぶち当たりました(単に使い方が悪かっただけではありますが)

以下のように、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)以降の場合、onStartonActivityResultなので、onActivityResultがコールされた時点で、ObserverがActiveになっているため、2回の更新どちらの値も受け取ることができます。

ところが、Android 12(API 31)までは、onActivityResultonStartなのでonActivityResultがコールされた時点で、ObserverがActiveになっていません。その後のonStartでActiveになります。そのため、最終的な値を1回のみ受け取るという違いが出てしまいます。

LiveDataをすべての値の更新を受け取れる前提で使うこと自体、良くない実装です。
ただ、このライフサイクルの違いは、開発に使用している端末が最新のOSだった場合、開発中には気づくことができず、下流工程で問題が見つかる。なんてことになったりするので注意しましょう。

32
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
9