android 判断应用是否在前台显示

  在一些场景下我们需要知道应用是否在前台显示,当不在前台显示的时候,一些后台进程可以暂时停止,比如一些查询任务、不必要的线程、不需要的渲染等,以减少对设备资源的占用。判断应用是否在前台通常可以使用一下方式:

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningTaskInfo> runnings = am.getRunningTasks(Integer.MAX_VALUE);
for(RunningTaskInfo info : runnings){
if(info.topActivity.equals(activityName)){
Log.i("my","前台显示");
}
}

因为系统api的变迁,也可以使用下面的方式:

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runnings = am.getRunningAppProcesses();
for(RunningAppProcessInfo running : runnings){
if(running.processName.equals(getPackageName())){
if(running.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
|| running.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE){
//前台显示...
}else{
//后台显示...
}
break;
}
}

这里后者判断加上了可见。比如,当用户点击了home键,这时候方法1和方法2都可以判断出来处于后台显示,然后再点击应用 再快速的打开其他的应用,这时候我们的应用就被其他应用盖在上面了,而方法1和方法2判断的结果都是在前台显示,这种情况下,就无法做出正确的判断,

通过研究和测试,发现使用下面的方式可以正确判断出来,方法如下:

public boolean isAppOnForeground(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
boolean isOnForground = false;
List<ActivityManager.RunningAppProcessInfo> runnings = am.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo running : runnings) {
if (running.processName.equals(getPackageName())) {
if (running.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
|| running.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
//前台显示...
Log.e("my", "前台显示");
isOnForground = true;
} else {
//后台显示...
Log.e("my", "后台显示");
isOnForground = false;
}
break;
}
}
String currentPackageName = "";
if (am.getRunningTasks(1).size() > 0) {
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
currentPackageName = cn.getPackageName();
}
// Log.e("my", "isAppOnForeground :" + currentPackageName + " getPackageName:" + getPackageName());
// return !TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(getPackageName());
return isOnForground;
}

下面的部分代码虽然没用到,但是不可省略,删去则不能正确判断。产生这个问题的原因,可能是因为线程管理进入list中时,必须需要同步安全的操作,找到对应的源代码如下:

public int addAppTask(@NonNull Activity activity, @NonNull Intent intent,
@Nullable TaskDescription description, @NonNull Bitmap thumbnail) {
Point size;
synchronized (this) {
ensureAppTaskThumbnailSizeLocked();
size = mAppTaskThumbnailSize;
}
final int tw = thumbnail.getWidth();
final int th = thumbnail.getHeight();
if (tw != size.x || th != size.y) {
Bitmap bm = Bitmap.createBitmap(size.x, size.y, thumbnail.getConfig()); // Use ScaleType.CENTER_CROP, except we leave the top edge at the top.
float scale;
float dx = 0, dy = 0;
if (tw * size.x > size.y * th) {
scale = (float) size.x / (float) th;
dx = (size.y - tw * scale) * 0.5f;
} else {
scale = (float) size.y / (float) tw;
dy = (size.x - th * scale) * 0.5f;
}
Matrix matrix = new Matrix();
matrix.setScale(scale, scale);
matrix.postTranslate((int) (dx + 0.5f), 0); Canvas canvas = new Canvas(bm);
canvas.drawBitmap(thumbnail, matrix, null);
canvas.setBitmap(null); thumbnail = bm;
}
if (description == null) {
description = new TaskDescription();
}
try {
return ActivityManagerNative.getDefault().addAppTask(activity.getActivityToken(),
intent, description, thumbnail);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

 

上一篇:数据结构Java实现02----线性表与顺序表


下一篇:一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator