简介
有时候我们需要判断App是处于前台还是后台,这样有利于我们处理一些业务
这里就说下如何判断App是处于前台还是后台
分别通过RunningTasks,RunningProcess 以及ActivityLifecycleCallbacks
实现
RunningTasks
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}")
}
}
getRunningTask方法在5.0以上已经被废弃,只会返回自己和系统的一些不敏感的task,不再返回其他应用的task,用此方法来判断自身App是否处于后台仍然有效,但是无法判断其他应用是否位于前台,因为不能再获取信息。
RunningProcess
/**
* 判断当前应用是否处于前台
*/
private fun isAppForeground(): Boolean {
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
/**
* 存活的App进程
*/
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
}
/**
* 用于判断那个应用是处于前台的
*/
private fun getForegroundApp(): String? {
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
var runningAppProcesses = activityManager.runningAppProcesses
if (runningAppProcesses.isNullOrEmpty()) {
return null
}
runningAppProcesses.forEach {
if (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND || it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
return it.processName
}
}
return null
}
Android5.0之后已经被废弃。
例如,在聊天类型的App中,常常需要常驻后台来不间断地获取服务器的消息,就需要把Service设置成START_STICKY,kill后会被重启(等待5s左右)来保证Service常驻后台。如果Service设置了这个属性,这个App的进程就会被判断为前台。代码表现为
appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
上述code永远成立,这样就永远无法判断到底那个是前台了。
ActivityLifecycleCallbacks
这里我们对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的实际数值返回回去
*/
fun getCount():Int = mCount
}
然后我们在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
//注册生命周期回调事件
registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
}
/**
* 用于判断当前进程是否处于前台
*/
fun isForegroundMethod(): Boolean = mActivityLifecycleCallbacks.getCount() > 0
companion object{
private var instance :LifeApplication?= null
fun getInstance () = instance!!
}
当我们不管是点击Back键还是Home键都会回调到onStop方法,我们在onStart和onStop中分别对mCount值做了加减
这样我们可以通过该数值来判断当前App是否处于前台还是后台