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();
        }
    } 

 

 

 

 

 

 

上一篇:微信x5webview接入实战


下一篇:动态权限<二>之淘宝、京东、网易新闻 权限申请交互设计对比分析