1 package leakcanary.internal 2 3 import android.app.Activity 4 import android.app.Application 5 import android.app.Application.ActivityLifecycleCallbacks 6 import leakcanary.ProcessInfo 7 import leakcanary.internal.friendly.mainHandler 8 import leakcanary.internal.friendly.noOpDelegate 9 10 /** 11 * Tracks whether the app is in background, based on the app's importance. 12 */ 13 internal class BackgroundListener( 14 private val processInfo: ProcessInfo, 15 private val callback: (Boolean) -> Unit 16 ) : ActivityLifecycleCallbacks by noOpDelegate() { 17 18 private val checkAppInBackground: Runnable = object : Runnable { runnull19 override fun run() { 20 val appInBackgroundNow = processInfo.isImportanceBackground 21 updateBackgroundState(appInBackgroundNow) 22 if (!appInBackgroundNow) { 23 mainHandler.removeCallbacks(this) 24 mainHandler.postDelayed(this, BACKGROUND_REPEAT_DELAY_MS) 25 } 26 } 27 } 28 updateBackgroundStatenull29 private fun updateBackgroundState(appInBackgroundNow: Boolean) { 30 if (appInBackground != appInBackgroundNow) { 31 appInBackground = appInBackgroundNow 32 callback.invoke(appInBackgroundNow) 33 } 34 } 35 36 private var appInBackground = false 37 installnull38 fun install(application: Application) { 39 application.registerActivityLifecycleCallbacks(this) 40 updateBackgroundState(appInBackgroundNow = false) 41 checkAppInBackground.run() 42 } 43 uninstallnull44 fun uninstall(application: Application) { 45 application.unregisterActivityLifecycleCallbacks(this) 46 updateBackgroundState(appInBackgroundNow = false) 47 mainHandler.removeCallbacks(checkAppInBackground) 48 } 49 onActivityPausednull50 override fun onActivityPaused(activity: Activity) { 51 mainHandler.removeCallbacks(checkAppInBackground) 52 mainHandler.postDelayed(checkAppInBackground, BACKGROUND_DELAY_MS) 53 } 54 onActivityResumednull55 override fun onActivityResumed(activity: Activity) { 56 updateBackgroundState(appInBackgroundNow = false) 57 mainHandler.removeCallbacks(checkAppInBackground) 58 } 59 60 companion object { 61 private const val BACKGROUND_DELAY_MS = 1000L 62 private const val BACKGROUND_REPEAT_DELAY_MS = 5000L 63 } 64 } 65