前提
以下によると、
ActivityやFragmentのOnResumeなどのライフサイクルのOverrideメソッドが非推奨となっています。
Do not override lifecycle methods such as onResume in Activities or Fragments. Use LifecycleObserver instead. If the app needs to perform work when the lifecycle reaches a certain Lifecycle.State, use the repeatOnLifecycle API.
翻訳すると…
アクティビティやフラグメントの onResume などのライフサイクル メソッドをオーバーライドしないようにします。代わりに LifecycleObserver を使用します。ライフサイクルが特定の Lifecycle.State に達したときにアプリが処理を実行する必要がある場合は、repeatOnLifecycle API を使用します。
ライフサイクル関連の処理を実装する場合は、代わりにLifecycleObserverを使用する必要があるとのこと。
ちょうど実装する機会があったので、その時の備忘を記載します。
実装
実際に行った実装はシンプルです。
以下のようなDefaultLifecycleObserver
を継承した
LifecycleObserver
のクラスを作成します。
class SampleLifecycleObserver : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
Log.d("Lifecycle", "onResume")
}
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
Log.d("Lifecycle", "onStart")
}
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
Log.d("Lifecycle", "onPause")
}
override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
Log.d("Lifecycle", "onStop")
}
}
上記で実装しているライフサイクルは、
onResume
, onStart
, onPause
, onStop
の4つのみですが、他にもonCreate
やonDestroy
が用意されています。
ライフサイクル毎に処理を実施したい場合は、
各ライフサイクルの中に実行したい処理を実際に書くだけです。
(今回はログ出力だけ実施させてます)
あとは、この追加したクラスを以下のように
addObserver
関数で登録するだけです。
init {
lifecycle.addObserver(SampleLifecycleObserver())
}
これでライフサイクルを検知して処理を実行することが可能になります。
少し余談
上記実装の他にライフサイクル検知する処理で
ProcessLifecycleOwner
と呼ばれるものがあります。
こちらもLifecycleObserver
と同じように
Observerを登録して使用しますが、以下のようなクセがあります。
Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP, events will be dispatched with a delay after a last activity passed through them. This delay is long enough to guarantee that ProcessLifecycleOwner won't send any events if activities are destroyed and recreated due to a configuration change.
上記によると、どうやらonStop
またはonPause
は
delayによる遅延(数秒ほど?)の後に検知されるようです。
これにより何が起こりうるか?
例えば、
「アプリがバックグラウンドになった時、非同期通信中であれば通信遮断する」といった動作を実現したいとします。
そこでonStop
のタイミングで通信遮断する実装にした場合、以下のようになる恐れがあります。
非同期通信中
↓
通信完了してレスポンス返却済み
↓
(delayによる遅延で)onStop()が検知されて通信遮断
つまり、通信中にバックグラウンドにしてもdelayによる遅延のせいで、
その間に通信レスポンスが返ってonStopの検知が通信化完了後となる、といった動きになってしまうということです。
これではアプリバックグラウンドのタイミングで通信が遮断されないというわけです。
ProcessLifecycleOwner
を使用する場合は、この検知遅れに注意して実装する必要があります。(私も実際にここでつまずきましたので…)