Blog

OnLifecycleEventより、DefaultLifecycleObserverを使おう

Androidの複雑なlifecycleに対応するのに、jetpackのLifecycleObserver等の仕組みは非常に強力です。

LifecycleObserverにはいくつか種類がありますが、LifecycleObserverのinterfaceにOnLifecycleEventのアノテーションを付けてやる方法が一番一般的だと思っていました。

しかし、java 8環境下ではDefaultLifecycleObserverのほうが強く推奨されていたので、その説明と、移行に関する注意点をまとめてみます。

OnLifecycleEventとDefaultLifecycleObserverの比較

Java 7 では、以下のようにOnLifecycleEvent のアノテーションを使ってLifecycleObserverを作成します。

class TestObserver: LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop(owner: LifecycleOwner) {
         // code
    }
}

引数がなくても動いたり、

class TestObserver: LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop() {
         // code
    }
}

ON_ANYというイベントも設定できるが面白いですね

class TestObserver: LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onAny(source: LifecycleOwner, event: Event) {
         // code
    }
}

Java 8環境下ではDefaultLifecycleObserverを使って以下のように書けます。

class TestObserver: DefaultLifecycleObserver {
   override fun onStop(owner: LifecycleOwner) {
         // code
    }
}

アノテーションがなくなりすっきりし、また引数等を間違えることがなくなりました。

これは、Java 8からinterfaceのデフォルト実装が可能になったことで実現されています。

DefaultLifecycleObserverの説明に、

If you use Java 8 language, always prefer it over annotations.

とあるように、Java 8を使ってる場合は常にDefaultLifecycleObserverが推奨されます。

androidアプリ開発を必ずしもJava 8でする必要はないと思いますが、多くの場合Java 8で開発されることが多くなってきていると思います。

その場合、DefaultLifecycleObserverを使うようにしましょう。

移行方法

Java 8が有効になってない場合は、app moduleのbuild.gradleに以下を追記してください。

android {
  …
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

Lifecycleの依存関係を修正します

dependencies {
  ...
-  kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
+  implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
}

アノテーションは必要なくなったので、kaptは外して、代わりにJava 8用の依存関係を追加します。

あとはDefaultLifecycleObserverに修正していくだけです。

1点、lifecycle-compiler を消してもbuildは通るが、イベントが正しく動かなくなるので注意してください。

まとめ

僕が長らく勘違いしていたことをまとめてみました。(ドキュメントはちゃんと読みましょう)

なにか参考になれば幸いです。

人気の記事

kotlin coroutinesのFlow, SharedFlow, StateFlowを整理する

Jetpack ComposeとKotlin Coroutinesを連携させる

Layout Composableを使って複雑なレイアウトを組む【Jetpack Compose】

テスト用Dispatcherの使い分け【Kotlin Coroutines】

Flow.combineの内部実装がすごい話

Jetpack ComposeのRippleエフェクトを深堀り、カスタマイズも