检查 Android 应用程序是否在后台运行 [英] Checking if an Android application is running in the background

查看:28
本文介绍了检查 Android 应用程序是否在后台运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所谓后台,我的意思是用户当前看不到应用程序的所有活动?

By background, I mean none of the application's activities are currently visible to the user?

推荐答案

检测你的应用程序是否在后台运行的方法很少,但只有一种方法是完全可靠的:

There are few ways to detect whether your application is running in the background, but only one of them is completely reliable:

  1. 正确的解决方案(致谢 DanCommonsWareNeTeInStEiN)
    使用 Activity.onPauseActivity.onResume 方法自行跟踪应用程序的可见性.在其他一些类中存储可见性"状态.好的选择是您自己实现 ApplicationService(还有 如果您想检查该服务的活动可见性,请使用此解决方案的一些变体).
     
    示例
    实现自定义Application 类(注意isActivityVisible() 静态方法):

  1. The right solution (credits go to Dan, CommonsWare and NeTeInStEiN)
    Track visibility of your application by yourself using Activity.onPause, Activity.onResume methods. Store "visibility" status in some other class. Good choices are your own implementation of the Application or a Service (there are also a few variations of this solution if you'd like to check activity visibility from the service).
     
    Example
    Implement custom Application class (note the isActivityVisible() static method):

public class MyApplication extends Application {

  public static boolean isActivityVisible() {
    return activityVisible;
  }  

  public static void activityResumed() {
    activityVisible = true;
  }

  public static void activityPaused() {
    activityVisible = false;
  }

  private static boolean activityVisible;
}

AndroidManifest.xml 中注册您的应用程序类:

Register your application class in AndroidManifest.xml:

<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

onPauseonResume 添加到项目中的每个 Activity(如果您愿意,可以为您的活动创建一个共同的祖先,但如果你的 Activity 已经从 MapActivity/ListActivity 等扩展而来,你仍然需要手动编写以下内容):

Add onPause and onResume to every Activity in the project (you may create a common ancestor for your Activities if you'd like to, but if your activity is already extended from MapActivity/ListActivity etc. you still need to write the following by hand):

@Override
protected void onResume() {
  super.onResume();
  MyApplication.activityResumed();
}

@Override
protected void onPause() {
  super.onPause();
  MyApplication.activityPaused();
}

 
更新
ActivityLifecycleCallbacks 已在 API 级别 14 (Android 4.0) 中添加.您可以使用它们来跟踪您的应用程序的活动当前是否对用户可见.查看下面的Cornstalks 的回答了解详情.

 
Update
ActivityLifecycleCallbacks were added in API level 14 (Android 4.0). You can use them to track whether an activity of your application is currently visible to the user. Check Cornstalks' answer below for the details.

错了
我曾经建议以下解决方案:

The wrong one
I used to suggest the following solution:

您可以使用 <检测当前的前台/后台应用程序code>ActivityManager.getRunningAppProcesses() 返回 RunningAppProcessInfo 记录的列表.要确定您的应用程序是否在前台,请检查 RunningAppProcessInfo.importance 字段是否与 RunningAppProcessInfo.IMPORTANCE_FOREGROUND 相等,而 RunningAppProcessInfo.processName 与您的应用程序相等包裹名字.

You can detect currently foreground/background application with ActivityManager.getRunningAppProcesses() which returns a list of RunningAppProcessInfo records. To determine if your application is on the foreground check RunningAppProcessInfo.importance field for equality to RunningAppProcessInfo.IMPORTANCE_FOREGROUND while RunningAppProcessInfo.processName is equal to your application package name.

此外,如果您从应用程序 UI 线程中调用 ActivityManager.getRunningAppProcesses(),无论它是否实际上在前台,它都会为您的任务返回重要性 IMPORTANCE_FOREGROUND.在后台线程中调用它(例如通过 AsyncTask),它将返回正确的结果.

Also if you call ActivityManager.getRunningAppProcesses() from your application UI thread it will return importance IMPORTANCE_FOREGROUND for your task no matter whether it is actually in the foreground or not. Call it in the background thread (for example via AsyncTask) and it will return correct results.

虽然此解决方案可能有效(并且在大多数情况下确实有效),但我强烈建议您不要使用它.这就是原因.正如 Dianne Hackborn 所写:

While this solution may work (and it indeed works most of the time) I strongly recommend to refrain from using it. And here's why. As Dianne Hackborn wrote:

这些 API 不是供应用程序基于其 UI 流使用,而是用于向用户显示正在运行的应用程序或任务管理器等.

These APIs are not there for applications to base their UI flow on, but to do things like show the user the running apps, or a task manager, or such.

是的,在内存中保存了这些东西的列表.但是,它在另一个进程中关闭,由与您的线程分开运行的线程管理,而不是您可以指望 (a) 及时看到以做出正确决定或 (b) 在您返回时拥有一致的图片.另外,关于下一个"活动要进行什么的决定总是在切换发生的时候完成,直到那个确切的点(活动状态被短暂锁定以进行切换)我们才确切地知道接下来会发生什么.

Yes there is a list kept in memory for these things. However, it is off in another process, managed by threads running separately from yours, and not something you can count on (a) seeing in time to make the correct decision or (b) have a consistent picture by the time you return. Plus the decision about what the "next" activity to go to is always done at the point where the switch is to happen, and it is not until that exact point (where the activity state is briefly locked down to do the switch) that we actually know for sure what the next thing will be.

这里的实现和全局行为不能保证在未来保持不变.

And the implementation and global behavior here is not guaranteed to remain the same in the future.

我希望在我在 SO 上发布答案之前读过这篇文章,但希望现在承认我的错误还为时不晚.

I wish I had read this before I posted an answer on the SO, but hopefully it's not too late to admit my error.

另一个错误的解决方案
Droid-Fu 在其中一个答案中提到的库使用 ActivityManager.getRunningTasks 作为其 isApplicationBroughtToBackground 方法.请参阅上面 Dianne 的评论,也不要使用该方法.

Another wrong solution
Droid-Fu library mentioned in one of the answers uses ActivityManager.getRunningTasks for its isApplicationBroughtToBackground method. See Dianne's comment above and don't use that method either.

这篇关于检查 Android 应用程序是否在后台运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆