Androidのアプリ終了(タスクキル)を検知する方法(onDestroy)
2021/01/12

Androidアプリのライフサイクルを管理したい場合は、皆さんApplicationクラスを使っていると思います。
class MainApplication: Application(), Application.ActivityLifecycleCallbacks {
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(this)
}
override fun onActivityDestroyed(activity: Activity?) {
// アプリを終了しても呼ばれない
}
}
ただし、このままではアプリ終了時のonActivityDestroyedだけが呼ばれないんですよね。
調べてみるとServiceクラスを使うと検出できるらしいので試してみると、無事にonActivityDestroyedが呼ばれるようになりました。
私の使っている改良版がこちら。
import android.app.Application
import android.app.Activity
import android.app.Service
import android.content.Intent
import android.os.Bundle
import android.os.IBinder
class MainApplication: Application(), Application.ActivityLifecycleCallbacks {
// SharedPreferencesなどで使うためのシングルトン
companion object {
lateinit var shared: MainApplication
private set
}
init {
shared = this
}
private var startedCount = 0
var isRunningInForeground = false
// Life cycle
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(this)
// サービスを開始する
startService(Intent(this, DestroyingService::class.java))
}
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
}
override fun onActivityStarted(activity: Activity?) {
if (startedCount == 0) {
isRunningInForeground = true
onActivityEnteredInForeground(activity)
}
startedCount += 1
}
override fun onActivityResumed(activity: Activity?) {
}
override fun onActivityPaused(activity: Activity?) {
}
override fun onActivityStopped(activity: Activity?) {
startedCount -= 1
if (startedCount == 0) {
isRunningInForeground = false
onActivityEnteredInBackground(activity)
}
}
private fun onActivityEnteredInForeground(activity: Activity?) {
// アプリがフォアグラウンドになった時
}
private fun onActivityEnteredInBackground(activity: Activity?) {
// アプリがバックグラウンドになった時
}
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
}
override fun onActivityDestroyed(activity: Activity?) {
// アプリをタスク画面から終了させた時
}
// Destroy検出用のServiceクラス
class DestroyingService: Service() {
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
}
DestroyingServiceクラスをAndroidManifest.xmlへ登録しておく。
<application
android:name=".MainApplication"
android:label="@string/app_name_display"
android:allowBackup="false"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme">
<service
android:name=".MainApplication$DestroyingService"
android:stopWithTask="false" />
</application>
これで基本的なタイミングは全て検出できると思います。