APP怎么判断自己是处于前台还是后台

RunningTask

原理:
当一个 App 处于前台的时候,会处于 RunningTask 的这个栈的栈顶,所以我们可以取出 RunningTask 的栈顶的任务进程,看他与我们的想要判断的 App 的包名是否相同,来达到效果

缺点:
getRunningTask 方法在 Android5.0 以上已经被废弃,只会返回自己和系统的一些不敏感的 task,不再返回其他应用的 task,用此方法来判断自身 App 是否处于后台,仍然是有效的,但是无法判断其他应用是否位于前台,因为不再能获取信息

<uses-permission android:name="android.permission.GET_TASKS" />  
    public static boolean isApplicationBroughtToBackground(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                return true;
            }
        }
        return false;
    }

RunningProcess

原理
通过 runningProcess 获取到一个当前正在运行的进程的 List,我们找到与想要判断app包名一样的进程并判断这个进程的 importance 属性是否是前台进程,如果是那这个 App 就处于前台
缺点:
在聊天类型的 App 中,常常需要常驻后台来不间断的获取服务器的消息,这就需要我们把 Service 设置成 START_STICKY,kill 后会被重启(等待 5 秒左右)来保证 Service 常驻后台。如果 Service 设置了这个属性,这个 App 的进程就会被判断是前台,代码上的表现就是 appProcess.importance 的值永远是 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,这样就永远无法判断出到底哪个是前台了。

  public static boolean isBackground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List appProcesses = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(context.getPackageName())) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                    Log.i("后台", appProcess.processName);
                    return true;
                }else{
                    Log.i("前台", appProcess.processName);
                    return false;
                }
            }
        }
        return false;
    }

ActivityLifecycleCallbacks

public class Application extends ContextWrapper implements ComponentCallbacks2 {
    。。。
    public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }
    。。。
}

Application类里有ActivityLifecycleCallbacks回调接口,我们在Application的onCreate()注册该接口。

一个app内从ActivityA跳转到ActivityB的回调方法如下:
A.onPause() -> B.onStart() -> B.onResume() -> A.onStop()

通过这些回调我们可以在onStart()和onStop()中进行计数,如果start就+1,onstop就-1,这样可以根据计数是否为0来判断是否是前台了。

/proc目录下的process进程信息

原理:
Linux系统内核会把process进程信息保存在/proc目录下,Shell命令去获取的他,再根据进程的属性判断是否为前台。
优点:
不需要任何权限
可以判断任意一个应用是否在前台,而不局限在自身应用
缺点:
当/proc下文件夹过多时,此方法是耗时操作

你可能感兴趣的:(Android)