【Android】ProcessLifecycleOwnerを使ってアプリのフォアグラウンドorバックグラウンドを判定する


前提

Android Studio 4.1.2
Kotlin 1.3.72

アプリのフォアグラウンドorバックグラウンドの判定について仕事で調べる機会があったので記事にしておくことにしました。調べていくとライフサイクルステータスの監視に辿り着いたのでそれも記載しておきます。

ライブラリのバージョンについてはこちらを見て、執筆時点の安定版である2.2.0を使っています。

目標

アプリのフォアグラウンドorバックグラウンドを判定する。

実装

ライフサイクルステータスの監視

ProcessLifecycleOwnerクラスを使うことで実現できます。LifecycleObserverインターフェースをOnLifecycleEventアノテーションを使って実装するやり方と、アノテーションを使わずにDefaultLifecycleObserverインターフェースを実装するやり方があります。

こちらにも書いてありますが、Java 7(以下?)を使っているならLifecycleObserverインターフェースを、Java 8(以上?)を使っているならDefaultLifecycleObserverインターフェースを使うことが推奨されています。

LifecycleObserverインターフェースの実装

ライブラリを追加します。

def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"


LifecycleObserverインターフェースを実装したMyLifecycleObserverクラスを作成し、オブザーバーを追加します。OnLifecycleEventアノテーションを使ったメソッドは自由に命名でき、仮引数も省略できます。

package com.example.testapplication

import android.app.Application
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(MyLifecycleObserver())
    }

    private class MyLifecycleObserver : LifecycleObserver {
        companion object {
            private const val TAG = "MyLifecycleObserver"
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        fun onCreate(owner: LifecycleOwner) {
            Log.d(TAG, "onCreate")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        fun onDestroy(owner: LifecycleOwner) {
            Log.d(TAG, "onDestroy")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        fun onPause(owner: LifecycleOwner) {
            Log.d(TAG, "onPause")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        fun onResume(owner: LifecycleOwner) {
            Log.d(TAG, "onResume")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        fun onStart(owner: LifecycleOwner) {
            Log.d(TAG, "onStart")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        fun onStop(owner: LifecycleOwner) {
            Log.d(TAG, "onStop")
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
        fun onAny(owner: LifecycleOwner, event: Lifecycle.Event) {
            Log.d(TAG, "onAny")
        }
    }
}


DefaultLifecycleObserverインターフェース

ライブラリを追加します。

def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"


DefaultLifecycleObserverインターフェースを実装したMyDefaultLifecycleObserverクラスを作成し、オブザーバーを追加します。

package com.example.testapplication

import android.app.Application
import android.util.Log
import androidx.lifecycle.*

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(MyDefaultLifecycleObserver())
    }

    private class MyDefaultLifecycleObserver : DefaultLifecycleObserver {
        companion object {
            private const val TAG = "MyDefaultLifecycleObserver"
        }

        override fun onCreate(owner: LifecycleOwner) {
            Log.d(TAG, "onCreate")
        }

        override fun onDestroy(owner: LifecycleOwner) {
            Log.d(TAG, "onDestroy")
        }

        override fun onPause(owner: LifecycleOwner) {
            Log.d(TAG, "onPause")
        }

        override fun onResume(owner: LifecycleOwner) {
            Log.d(TAG, "onResume")
        }

        override fun onStart(owner: LifecycleOwner) {
            Log.d(TAG, "onStart")
        }

        override fun onStop(owner: LifecycleOwner) {
            Log.d(TAG, "onStop")
        }
    }
}


現在のライフサイクルステータスを取得&判定する

現在のライフサイクルステータスを取得&判定するだけなら、ライフサイクルステータスの監視はしなくても実現できました。Lifecycleクラスを使用することで、現在のライフサイクルステータスを取得できます。

// 取得
val state = ProcessLifecycleOwner.get().lifecycle.currentState


Lifecycle.StateクラスにはisAtLeastメソッドという、実行時にアプリが引数のライフサイクルステータスかどうかをbooleanで返すメソッドがあるので、それを使ってフォアグラウンドorバックグラウンドを判定できます。
ライフサイクルステータスがLifecycle.State.RESUMEDの場合はアプリがフォアグラウンドにあることになるので、isAtLeastメソッドでLifecycle.State.RESUMEDかどうかを判定することでフォアグラウンドorバックグラウンドの判定を実現できました。Lifecycle.Stateの定義についてはこちらを参照。

// trueならフォアグラウンド
ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)


ライフサイクルステータスについてはこちらの記事↓がわかりやすかったです。 qiita.com