在一些場景下咱們須要知道應用是否在前臺顯示,當不在前臺顯示的時候,一些後臺進程能夠暫時中止,好比一些查詢任務、沒必要要的線程、不須要的渲染等,以減小對設備資源的佔用。判斷應用是否在前臺一般可使用一下方式:canvas
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的變遷,也可使用下面的方式: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判斷的結果都是在前臺顯示,這種狀況下,就沒法作出正確的判斷,安全
經過研究和測試,發現使用下面的方式能夠正確判斷出來,方法以下:post
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(); } }