Checking if an Android application is running in the background(检查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:
正确的解决方案(致谢 Dan, CommonsWare 和 NeTeInStEiN)
使用Activity.onPause
、Activity.onResume
方法自行跟踪应用程序的可见性.将可见性"状态存储在其他类中.不错的选择是您自己的Application
或Service
实现(还有 如果您想检查服务中的活动可见性,请使用此解决方案的一些变体.
示例
实现自定义Application
类(注意isActivityVisible()
静态方法):
The right solution (credits go to Dan, CommonsWare and NeTeInStEiN)
Track visibility of your application by yourself usingActivity.onPause
,Activity.onResume
methods. Store "visibility" status in some other class. Good choices are your own implementation of theApplication
or aService
(there are also a few variations of this solution if you'd like to check activity visibility from the service).
Example
Implement customApplication
class (note theisActivityVisible()
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
中注册你的应用类:
<application
android:name="your.app.package.MyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name" >
将 onPause
和 onResume
添加到项目中的每个 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:
您可以使用 ActivityManager.getRunningAppProcesses()
返回 RunningAppProcessInfo
记录列表.要确定您的应用程序是否在前台,请检查 RunningAppProcessInfo.importance
字段是否等于 RunningAppProcessInfo.IMPORTANCE_FOREGROUND
而 RunningAppProcessInfo.processName
等于您的应用程序包裹名字.
You can detect currently foreground/background application with
ActivityManager.getRunningAppProcesses()
which returns a list ofRunningAppProcessInfo
records. To determine if your application is on the foreground checkRunningAppProcessInfo.importance
field for equality toRunningAppProcessInfo.IMPORTANCE_FOREGROUND
whileRunningAppProcessInfo.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应用程序是否在后台运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:检查Android应用程序是否在后台运行


- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- Android - 拆分 Drawable 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01
- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01