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<ActivityManager.RunningTaskInfo> 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<ActivityManager.RunningAppProcessInfo> 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下文件夹过多时,此方法是耗时操作