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

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

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

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

 

 

 

 

 

 

目录
相关文章
|
5天前
|
搜索推荐 Java Android开发
打造个性化安卓应用:从设计到发布的全程指南
【9月更文挑战第15天】本篇文章将带领读者踏上一段激动人心的旅程,从构思一个独特的安卓应用想法开始,直至将其变为现实并成功发布。我们将一起探索如何捕捉灵感、设计界面、编写代码以及最终将应用推向市场。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供宝贵的洞见和实用的技巧,让你的应用在竞争激烈的市场中脱颖而出。
35 17
|
1天前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
28 15
|
1天前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
13 5
|
2天前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
25 3
|
2天前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
14 2
|
10天前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
27 5
|
8天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
21 1
|
16天前
|
XML Java Android开发
探索Android开发之旅:打造你的第一个应用
【9月更文挑战第4天】在这篇专为初学者设计的文章中,我们将一起踏上激动人心的Android开发之旅。从设置开发环境到实现一个简单的“Hello World”应用,每一步都充满了发现和学习。文章将引导你理解Android开发的基础知识,并鼓励你动手实践。让我们开始吧,创造你的第一款Android应用,开启技术世界的新篇章!
|
18天前
|
存储 缓存 搜索推荐
打造个性化天气应用:Android 平台上的天气预报小助手
【9月更文挑战第2天】在这篇文章中,我们将一起探索如何从零开始构建一个简单却功能强大的天气应用。通过这个指南,你将学会如何在 Android 平台上使用 Java 编程语言和相关 API 来创建你自己的天气预报小助手。文章不仅提供了代码示例,还深入讨论了设计思路、用户界面优化以及数据管理等关键方面,旨在帮助初学者理解并实现一个完整的应用项目。