背景
在开发中,经常会需要判断应用是否在前台,根据应用的状态做逻辑处理。如根据应用是否在前台来判断是否需要弹框显示后台推送的消息,根据应用是否在前台来判断是否需要停止和开启某些服务,根据应用是否在前台来判断是否需要触发守护进程将主进程拉到前台来显示等。
判断方法
- 方式一:根据第一个运行任务栈来判断
public boolean isBackground(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService("activity");
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = ((ActivityManager.RunningTaskInfo) tasks.get(0)).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}
return false;
}
权限:android.permission.GET_TASKS
原理:当app处于前台的时候,会处于栈顶,取出栈顶的进程来判断与当前运行的的app包名是否相同。
注意:当从应用历史记录启动应用的时候,虽然最上层显示的是我们的应用,但是栈顶并不是我们的应用,而是launch应用。
- 方式二:使用当前运行进程判断
public static boolean isBackground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
boolean isBackground = true;
String processName = "empty";
for (RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(context.getPackageName())) {
processName = appProcess.processName;
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_CACHED) {
isBackground = true;
} else if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
|| appProcess.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
isBackground = false;
} else {
isBackground = true;
}
}
}
if (isBackground) {
Log.d(PERSISTENT_SERVICE, "后台:" + processName);
} else {
Log.d(PERSISTENT_SERVICE, "前台+" + processName);
}
return isBackground;
}
权限:无
原理:获取当前设备正在运行的进程列表,遍历找到我们自己应用的进程,判断我们自己应用进程的状态是否是前台进程。
IMPORTANCE_CACHED = 400//后台
IMPORTANCE_EMPTY = 500//空进程
MPORTANCE_FOREGROUND = 100//在屏幕最前端,可获取焦点
IMPORTANCE_SERVICE = 300//在服务中
IMPORTANCE_VISIBLE = 200//在屏幕前端、获取不到焦点
- 方式三:自己注册应用的生命周期监听回调,在对应的生命周期函数中加入记录方法。
public class BaseApplication extends Application{
private ActivityLifecycleCallbacks mCallbacks = new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
AppManagerUtils.getAppManager().addActivity(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
AppManagerUtils.getAppManager().removeActivity(activity);
}
};
@Override
public void onCreate() {
super.onCreate();
//注册监听每个activity的生命周期,便于堆栈式管理
if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
registerActivityLifecycleCallbacks(mCallbacks);
}
}
}
权限:无
原理:同一个进程的所有activity的生命周期都会进入该回调方法,因此通过记录activity显示的状态即可知道应用是否在前台了。
注意:该方式当activity异常退出的时候,即不走activity的生命周期时,会出现统计错误的情况,需要特殊处理该种异常。
总结
在项目中可以根据实际需求来选择合适的方式,如果是做守护进程的功能,则推荐方式二,如果是只是想记录所有activity的状态,方便退出应用,则推荐方式三。