经常在一些场景中,需要判断App是否在后台运行,从而做一些相应的处理。比如切换到后台运行后显示解锁界面等。接下来记录下平常用到的几种方法。
方法一
利用ActivityManager,获取RuningAppProcessInfo或者RuningTaskInfo这两种方法,代码如下:
1、获取RuningAppProcessInfo
1 | public boolean isAppForeground(Context context){ |
2、获取RuningTaskInfo
1 | public static boolean isAppForeground(Context context) { |
这两种方法有点类似于在使用windows的任务管理器,先抛开其性能方面的影响,这两种方法在,例如用户在进行应用间切换、按HOME键进入桌面、按开机键进入锁屏,都可能会影响到判断结果。而且获取RuningTaskInfo中getRunningTasks(1)方法在Android5.0中已经被废弃掉了,不推荐使用。
鉴于有一些问题的存在,这里推荐使用方法二。
方法二
先上代码:
1 | public class MyApplication extends Application { |
Android在SDK 14的时候提供了ActivityLifecycleCallbacks接口,可以通过这个它拿到App所有Activity的生命周期回调。
通过重写Application的onCreate()方法,或者在Application的无参构造方法内,调用registerActivityLifecycleCallbacks()方法,并实现ActivityLifecycleCallbacks接口。
分析:
首先简单回顾下Activity的生命周期,如果Activity调用了onResume(),那么这个Activity肯定是可见的,也就是运行在前台的。如果调用了onPause(),且没有Activity来调用onResume(),那么App就在后台运行。
根据这个原理,我们可以定义一个计数变量count初始为0,在ActivityLifecycleCallbacks回调的onActivityResumed()方法中加一,在onActivityPaused()方法中减一,如果count等于1,表示App在前台,如果count等于0,则表示在后台。
但是很快就会发现,如果在onActivityResumed()和onActivityPaused()中进行计数,会有个延时,导致判断不准确。
又回到Activity的生命周期中来,比如从Activity A跳转至Activity B,A和B的生命周期变化经历了如下的变化:
1 | A onPause ——> B onCreate ——> B onStart ——> B onResume ——> A onStop |
可以看出,在A onPause到B onResume之间,根据我们对count的判断,表示在此短暂的阶段应用处于后台运行状态,这样逻辑肯定是不正确的。
所以,正确的方式应该在ActivityLifecycleCallbacks回调的onActivityStarted()方法里面对count加一,在onActivityStopped()方法里减一。