[Android] 012. ApplicationクラスでLifecycleイベント

ApplicationクラスでLifeLifecycleイベントを扱いたい場合のあれこれです

ActivityLifecycleCallback

ActivityLifecycleCallbackを使用した場合です
https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallback

onActivityDestroyedが呼ばれなくServiceを使用してハンドリングの必要があるという話があったようですが現時点では呼ばれるようです

/**
 * ```AndroidManifest.xml
 * <application
 *     android:name=".Application"
 * ```
 */
class Application: android.app.Application() {
    override fun onCreate() {
        super.onCreate()
        registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks())
    }

    class ActivityLifecycleCallbacks: android.app.Application.ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, outState: Bundle?) {
            Log.d("App", "onActivityCreated")
        }

        override fun onActivityStarted(activity: Activity) {
            Log.d("App", "onActivityStarted")
        }

        override fun onActivityResumed(activity: Activity) {
            Log.d("App", "onActivityResumed")
        }

        override fun onActivityPaused(activity: Activity) {
            Log.d("App", "onActivityPaused")
        }

        override fun onActivityStopped(activity: Activity) {
            Log.d("App", "onActivityStopped")
        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
            Log.d("App", "onActivitySaveInstanceState")
        }

        override fun onActivityDestroyed(activity: Activity) {
            Log.d("App", "onActivityDestroyed")
        }
    }
}

ProcessLifecycleOwner

@OnLifecycleEventアノテーションが非推奨となっているためLifecycleObserverの代わりの実装が必要そうです

Annotation that can be used to mark methods on LifecycleObserver implementations that should be invoked to handle lifecycle events.
Deprecated
This annotation required the usage of code generation or reflection, which should be avoided. Use DefaultLifecycleObserver or LifecycleEventObserver instead.

警告通りDefaultLifecycleObserverかLifecycleEventObserverを使います

ProcessLifecycleOwnerを使用するためにはandroidx.lifecycle:lifecycle-processをimplementationする必要があります

DefaultLifecycleObserver

https://developer.android.com/reference/androidx/lifecycle/DefaultLifecycleObserver
class Application: android.app.Application() {
    private var lifecycleObserver = object : DefaultLifecycleObserver {
        override fun onCreate(owner: LifecycleOwner) {
            super.onCreate(owner)
            Log.d("App", "onCreate")
        }

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

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

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

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

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

    override fun onCreate() {
        super.onCreate()
        // androidx.lifecycle:lifecycle-process
        ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleObserver)
    }
}

LifecycleEventObserver

LifecycleEventObserver  |  Android Developers
class Application: android.app.Application() {
    private var lifecycleObserver = LifecycleEventObserver { _, event ->
        when(event) {
            Lifecycle.Event.ON_CREATE -> {
                Log.d("App", "ON_CREATE")
            }

            Lifecycle.Event.ON_START -> {
                Log.d("App", "ON_START")
            }

            Lifecycle.Event.ON_RESUME -> {
                Log.d("App", "ON_RESUME")
            }

            Lifecycle.Event.ON_PAUSE -> {
                Log.d("App", "ON_PAUSE")
            }

            Lifecycle.Event.ON_STOP -> {
                Log.d("App", "ON_STOP")
            }

            Lifecycle.Event.ON_DESTROY -> {
                Log.d("App", "ON_DESTROY")
            }

            Lifecycle.Event.ON_ANY -> {
                Log.d("App", "ON_ANY")
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        // androidx.lifecycle:lifecycle-process
        ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleObserver)
    }
}

ProcessLifecycleOwnerを使用した場合はonDestroyが呼び出されないようです

Service

ServiceでonDestroyをハンドリング
stopWithTaskがfalseの場合はonTaskRemoved()は呼び出されず、falseの場合はstopSelf()を呼び出さないとonDestroy()が呼び出されないようです

class AppService : Service() {
    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        Log.d("App", "Service::onCreate")
    }

    override fun onTaskRemoved(rootIntent: Intent?) {
        super.onTaskRemoved(rootIntent)
        Log.d("App", "Service::onTaskRemoved")
        stopSelf()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("App", "Service::onDestroy")
    }
}
class Application: android.app.Application() {
    override fun onCreate() {
        super.onCreate()
        startService(Intent(this, AppService::class.java))
    }
}
<manifest>
<application>
    <service android:name=".Application$AppService" android:stopWithTask="false" />
</application>
</manifest>

実際に使用する場合は以下のような実装になると思います
stopWithTaskはtrueにしています

class Application: android.app.Application() {
    override fun onCreate() {
        super.onCreate()
        startService(Intent(this, AppService::class.java))
    }

    fun onDestroy() {
        Log.d("App", "onDestroy")
    }

    class AppService : Service() {
        override fun onBind(intent: Intent?): IBinder? {
            return null
        }

        override fun onDestroy() {
           Log.d("App", "Service::onDestroy")
            // (namespace)にアプリのnamespaceを入れてください
            var app = application as (namespace).Application
            app.onDestroy()

            super.onDestroy()
        }
    }
}

Android Studio Giraffe 2022.3.1 built on June 29, 2023