如何判斷APP在前臺還是后臺?
如何判斷一個APP在前臺還是后臺?可以通過RunningTasks,RunningProcess 以及ActivityLifecycleCallback判定。
RunningTasks方式
注意:getRunningTask方法在5.0以上已經(jīng)被廢棄,只能返回自己和系統(tǒng)的一些不敏感的task,不再返回其他應用的task,用此方法來判斷自身App是否處于后臺是有效的,但是無法判斷其他應用是否處于前臺。
private fun getTopApplication() {
//首先獲取到ActivityManager
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
if (activityManager.getRunningTasks(1) == null){
Log.e(TAG, "getForegroundActivity: ")
return
}
var runningTaskInfo = activityManager.getRunningTasks(1)[0]
if (runningTaskInfo == null) {
Log.e(TAG, "runningTaskInfo is null")
return
}
runningTaskInfo.topActivity?.let {
Log.e(TAG, "top application is ${it.packageName}")
}
}
RunningProcess方式
注意:RunningProcess方法在5.0以上已經(jīng)被廢棄,例如,在聊天類型的App中,大部分時間需要常駐后臺來不間斷地獲取服務器的消息,就必須把Service設置成START_STICKY,kill后會被重啟(等待5s左右)來保證Service常駐后臺。如果Service設置了這個屬性,這個App的進程就可以判斷為前臺。
appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
private fun isAppForeground(): Boolean {
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
var runningAppProcesses = activityManager.runningAppProcesses
if (runningAppProcesses == null) {
Log.e(TAG, "runningAppProcesses is null")
return false
}
runningAppProcesses.forEach {
if (it.processName == packageName && (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)) {
return true
}
}
return false
}
ActivityLifecycleCallbacks方式
class MyActivityLifecycleCallbacks(
var onActivityCreatedAction: ((Activity, Bundle?) -> Unit)? = null,
var onActivityStartedAction: ((Activity) -> Unit)? = null,
var onActivityResumedAction: ((Activity) -> Unit)? = null,
var onActivityPausedAction: ((Activity) -> Unit)? = null,
var onActivityStoppedAction: ((Activity) -> Unit)? = null,
var onActivitySaveInstanceStateAction: ((Activity, Bundle) -> Unit)? = null,
var onActivityDestroyedAction: ((Activity) -> Unit)? = null
) : Application.ActivityLifecycleCallbacks {
private var mCount=0
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
onActivityCreatedAction?.invoke(activity, savedInstanceState)
}
override fun onActivityStarted(activity: Activity) {
mCount++
onActivityStartedAction?.invoke(activity)
}
override fun onActivityResumed(activity: Activity) {
onActivityResumedAction?.invoke(activity)
}
override fun onActivityPaused(activity: Activity) {
onActivityPausedAction?.invoke(activity)
}
override fun onActivityStopped(activity: Activity) {
mCount--
onActivityStoppedAction?.invoke(activity)
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
onActivitySaveInstanceStateAction?.invoke(activity, outState)
}
override fun onActivityDestroyed(activity: Activity) {
onActivityDestroyedAction?.invoke(activity)
}
/**
* 這里我們把mCount的實際數(shù)值返回回去
*/
fun getCount():Int = mCount
}
這里我們對ActivityLifecycleCallbacks的實現(xiàn)類做了一層封裝,利用Kotlin的高階函數(shù),當我們需要去實現(xiàn)那個聲明周期的回調(diào)的時候,就通過高階函數(shù)來提供回調(diào)處理,否則默認不做任何處理。然后我們在Application的onCreate中進行注冊:
class LifeApplication : Application() {
private val TAG = "LifeApplication"
private val mActivityLifecycleCallbacks by lazy {
MyActivityLifecycleCallbacks(
onActivityCreatedAction = { activit, bundle ->
Log.e(TAG, "onCreate: ")
},
onActivityStoppedAction = { activity ->
Log.e(TAG, "onStop ")
},
onActivityDestroyedAction = { activity ->
Log.e(TAG, "onDestroy")
})
}
override fun onCreate() {
super.onCreate()
instance = this
//注冊生命周期回調(diào)事件
registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
}
/**
* 用于判斷當前進程是否處于前臺
*/
fun isForegroundMethod(): Boolean = mActivityLifecycleCallbacks.getCount() > 0
companion object{
private var instance :LifeApplication?= null
fun getInstance () = instance!!
}
當我們不管是點擊Back鍵還是Home鍵都會回調(diào)到onStop方法,我們在onStart和onStop中分別對mCount值做了加減,這樣我們可以通過該數(shù)值來判斷當前App是前臺還是后臺。