Android

App前后台运行状态判断

2016-07-07  本文已影响569人  vergo

经常在一些场景中,需要判断App是否在后台运行,从而做一些相应的处理。比如切换到后台运行后显示解锁界面等。接下来记录下平常用到的几种方法。

方法一

利用ActivityManager,获取RuningAppProcessInfo或者RuningTaskInfo这两种方法,代码如下:
1、获取RuningAppProcessInfo

public boolean isAppForeground(Context context){
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Service.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList = activityManager.getRunningAppProcesses();
    if (runningAppProcessInfoList==null){
        return false;
    }
    for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcessInfoList) {
        if (processInfo.processName.equals(context.getPackageName()) &&
                processInfo.importance==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
            return true;
        }
    }
    return false;
}

2、获取RuningTaskInfo

public static boolean isAppForeground(Context context) {
    ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
    ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
    String currentPackageName = cn.getPackageName();
    if(!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(context.getPackageName())) {
        return true ;
    }
    return false ;
}

这两种方法有点类似于在使用windows的任务管理器,先抛开其性能方面的影响,这两种方法在,例如用户在进行应用间切换、按HOME键进入桌面、按开机键进入锁屏,都可能会影响到判断结果。而且获取RuningTaskInfo中getRunningTasks(1)方法在Android5.0中已经被废弃掉了,不推荐使用。

鉴于有一些问题的存在,这里推荐使用方法二。

方法二

先上代码:

public class MyApplication extends Application {
    public int count = 0;
    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {

            @Override
            public void onActivityStopped(Activity activity) {
                count--;
                if (count == 0) {
                    Log.v("vergo", "**********切到后台**********");
                }
            }

            @Override
            public void onActivityStarted(Activity activity) {
                if (count == 0) {
                    Log.v("vergo", "**********切到前台**********");
                }
                count++;
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }

            @Override
            public void onActivityResumed(Activity activity) {
            }

            @Override
            public void onActivityPaused(Activity activity) {
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
            }

            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            }
        });
    }
}

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的生命周期变化经历了如下的变化:

A onPause ——> B onCreate ——> B onStart ——> B onResume ——> A onStop

可以看出,在A onPause到B onResume之间,根据我们对count的判断,表示在此短暂的阶段应用处于后台运行状态,这样逻辑肯定是不正确的。

所以,正确的方式应该在ActivityLifecycleCallbacks回调的onActivityStarted()方法里面对count加一,在onActivityStopped()方法里减一。

上一篇 下一篇

猜你喜欢

热点阅读