本文翻译自:Checking if an Android application is running in the background

在后台,我的意思是用户当前看不到应用程序的任何活动?


#1楼

参考:https://stackoom.com/question/FNxW/检查Android应用程序是否在后台运行


#2楼

Idolon's answer is error prone and much more complicated althought repeatead here check android application is in foreground or not? Idolon的答案容易出错并且更复杂,尽管在这里重复检查Android应用程序是否在前台? and here Determining the current foreground application from a background task or service 在这里根据后台任务或服务确定当前的前台应用程序

There is a much more simpler approach: 有一种更简单的方法:

On a BaseActivity that all Activities extend: 所有活动都扩展的BaseActivity上:

protected static boolean isVisible = false;@Overridepublic void onResume(){super.onResume();setVisible(true);}@Overridepublic void onPause(){super.onPause();setVisible(false);}

Whenever you need to check if any of your application activities is in foreground just check isVisible() ; 每当您需要检查是否有任何应用程序活动处于前台时,只需检查 isVisible()

To understand this approach check this answer of side-by-side activity lifecycle: Activity side-by-side lifecycle 要了解这种方法,请检查并排活动生命周期的以下答案: 活动并排生命周期


#3楼

In my activities onResume and onPause I write an isVisible boolean to SharedPrefences. 在onResume和onPause活动中,我为SharedPrefences写了一个isVisible布尔值。

    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);Editor editor = sharedPrefs.edit();editor.putBoolean("visible", false);editor.commit();

And read it elsewhere when needed via, 并在需要时通过其他地方阅读,

    // Show a Toast Notification if App is not visible (ie in background. Not running, etc) SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);if(!sharedPrefs.getBoolean("visible", true)){...}

Maybe not elegant, but it works for me... 也许不优雅,但对我有用。


#4楼

DO NOT USE THIS ANSWER 请勿使用此答案

user1269737's answer is the proper (Google/Android approved) way to do this . user1269737的答案是执行此操作的正确方法(已获得Google / Android批准) 。 Go read their answer and give them a +1. 去阅读他们的答案,并给他们+1。

I'll leave my original answer here for posterity's sake. 为了后代的缘故,我将在这里保留原始答案。 This was the best available back in 2012, but now Android has proper support for this. 这是2012年提供的最好的软件,但现在Android对此已提供适当的支持。

Original answer 原始答案

The key is using ActivityLifecycleCallbacks (note that this requires Android API level 14 (Android 4.0)). 关键是使用ActivityLifecycleCallbacks (请注意,这需要Android API级别14(Android 4.0))。 Just check if the number of stopped activities is equal to the number of started activities. 只需检查已停止活动的数量是否等于已开始活动的数量即可。 If they're equal, your application is being backgrounded. 如果它们相等,则说明您的应用程序正在后台运行。 If there are more started activities, your application is still visible. 如果还有更多开始的活动,则您的应用程序仍然可见。 If there are more resumed than paused activities, your application is not only visible, but it's also in the foreground. 如果恢复的活动多于暂停的活动,则您的应用程序不仅可见,而且位于前台。 There are 3 main states that your activity can be in, then: visible and in the foreground, visible but not in the foreground, and not visible and not in the foreground (ie in the background). 然后,您的活动可以处于3个主要状态:可见和在前台,可见但不在前台,不可见且不在前台(即在后台)。

The really nice thing about this method is that it doesn't have the asynchronous issues getRunningTasks() does, but you also don't have to modify every Activity in your application to set/unset something in onResumed() / onPaused() . 关于此方法的真正getRunningTasks()是它没有getRunningTasks()的异步问题,但是您也不必修改应用程序中的每个Activity来设置或取消onResumed() / onPaused() It's just a few lines of code that's self contained, and it works throughout your whole application. 它仅包含几行代码,并且可以在整个应用程序中使用。 Plus, there are no funky permissions required either. 另外,也不需要时髦的权限。

MyLifecycleHandler.java: MyLifecycleHandler.java:

public class MyLifecycleHandler implements ActivityLifecycleCallbacks {// I use four separate variables here. You can, of course, just use two and// increment/decrement them instead of using four and incrementing them all.private int resumed;private int paused;private int started;private int stopped;@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {}@Overridepublic void onActivityDestroyed(Activity activity) {}@Overridepublic void onActivityResumed(Activity activity) {++resumed;}@Overridepublic void onActivityPaused(Activity activity) {++paused;android.util.Log.w("test", "application is in foreground: " + (resumed > paused));}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {}@Overridepublic void onActivityStarted(Activity activity) {++started;}@Overridepublic void onActivityStopped(Activity activity) {++stopped;android.util.Log.w("test", "application is visible: " + (started > stopped));}// If you want a static function you can use to check if your application is// foreground/background, you can use the following:/*// Replace the four variables above with these fourprivate static int resumed;private static int paused;private static int started;private static int stopped;// And these two public static functionspublic static boolean isApplicationVisible() {return started > stopped;}public static boolean isApplicationInForeground() {return resumed > paused;}*/
}

MyApplication.java: MyApplication.java:

// Don't forget to add it to your manifest by doing
// <application android:name="your.package.MyApplication" ...
public class MyApplication extends Application {@Overridepublic void onCreate() {// Simply add the handler, and that's it! No need to add any code// to every activity. Everything is contained in MyLifecycleHandler// with just a few lines of code. Now *that's* nice.registerActivityLifecycleCallbacks(new MyLifecycleHandler());}
}

@Mewzer has asked some good questions about this method that I'd like to respond to in this answer for everyone: @Mewzer提出了有关此方法的一些好问题,我想在此答案中为所有人答复:

onStop() is not called in low memory situations; 在内存不足的情况下不会调用onStop() is that a problem here? 这是一个问题吗?

No. The docs for onStop() say: onStop()的文档说:

Note that this method may never be called, in low memory situations where the system does not have enough memory to keep your activity's process running after its onPause() method is called. 请注意,在内存不足的情况下(系统的内存不足,无法在调用其onPause()方法后保持活动的进程继续运行),可能永远不会调用此方法。

The key here is "keep your activity's process running ..." If this low memory situation is ever reached, your process is actually killed (not just your activity). 这里的关键是“让您的活动的进程保持运行 ……”如果曾经遇到这种内存不足的情况,您的进程实际上将被杀死(而不仅仅是活动)。 This means that this method of checking for backgrounded-ness is still valid because a) you can't check for backgrounding anyway if your process is killed, and b) if your process starts again (because a new activity is created), the member variables (whether static or not) for MyLifecycleHandler will be reset to 0 . 这意味着这种检查背景色的方法仍然有效,因为a)如果您的进程被杀死,则无论如何都无法检查背景,并且b)如果您的进程再次启动(因为创建了新活动),则该成员MyLifecycleHandler变量(无论是否为静态)将重置为0

Does this work for configuration changes? 这对配置更改有效吗?

By default, no. 默认情况下,没有。 You have to explicitly set configChanges=orientation|screensize ( | with anything else you want) in your manifest file and handle the configuration changes, or else your activity will be destroyed and recreated. 您必须在清单文件中显式设置configChanges=orientation|screensize|和其他所需的内容)并处理配置更改,否则您的活动将被破坏并重新创建。 If you do not set this, your activity's methods will be called in this order: onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume . 如果未设置,则将按以下顺序调用活动的方法: onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume As you can see, there is no overlap (normally, two activities overlap very briefly when switching between the two, which is how this backgrounding-detection method works). 如您所见,没有重叠(通常,在两个活动之间切换时,两个活动会非常短暂地重叠,这就是这种背景检测方法的工作原理)。 In order to get around this, you must set configChanges so that your activity is not destroyed. 为了解决这个问题,您必须设置configChanges以便不会破坏您的活动。 Fortunately, I've had to set configChanges already in all of my projects because it was undesirable for my entire activity to get destroyed on screen rotate/resize, so I've never found this to be problematic. 幸运的是,我已经在所有项目中都已经设置了configChanges ,因为我不希望整个活动都在屏幕旋转/调整大小时被破坏,所以我从来没有发现这是有问题的。 (thanks to dpimka for refreshing my memory on this and correcting me!) (感谢dpimka刷新了我的记忆并纠正了我!)

One note: 一注:

When I've said "background" here in this answer, I've meant "your app is no longer visible." 当我在此答案中说“背景”时,我的意思是“您的应用不再可见”。 Android activities can be visible yet not in the foreground (for example, if there's a transparent notification overlay). Android活动是可见的,但不是在前台(例如,如果有透明的通知覆盖)。 That's why I've updated this answer to reflect that. 这就是为什么我更新了此答案以反映这一点的原因。

It's important to know that Android has a weird limbo moment when switching activities where nothing is in the foreground . 重要的是要知道,Android在切换没有任何前景的活动时会有一个奇怪的困境。 For this reason, if you check if your application is in the foreground when switching between activities (in the same app), you'll be told you're not in the foreground (even though your app is still the active app and is visible). 因此,如果您在活动(在同一应用程序中)之间进行切换时检查应用程序是否在前台,则系统会告知您您不在前台(即使您的应用程序仍然是活动应用程序并且可见) )。

You can check if your app is in the foreground in your Activity 's onPause() method after super.onPause() . 您可以 super.onPause() 之后检查您的应用程序是否处于ActivityonPause()方法的super.onPause() Just remember the weird limbo state I just talked about. 只要记住我刚才谈到的怪异的边缘状态即可。

You can check if your app is visible (ie if it's not in the background) in your Activity 's onStop() method after super.onStop() . 您可以 super.onStop() 之后的 ActivityonStop()方法中检查您的应用是否可见(即,是否不在后台super.onStop()


#5楼

I did my own implementation of ActivityLifecycleCallbacks. 我做了自己的ActivityLifecycleCallbacks实现。 I'm using SherlockActivity, but for normal Activity class might work. 我正在使用SherlockActivity,但对于正常的Activity类可能会起作用。

First, I'm creating an interface that have all methods for track the activities lifecycle: 首先,我正在创建一个接口,该接口具有用于跟踪活动生命周期的所有方法:

public interface ActivityLifecycleCallbacks{public void onActivityStopped(Activity activity);public void onActivityStarted(Activity activity);public void onActivitySaveInstanceState(Activity activity, Bundle outState);public void onActivityResumed(Activity activity);public void onActivityPaused(Activity activity);public void onActivityDestroyed(Activity activity);public void onActivityCreated(Activity activity, Bundle savedInstanceState);
}

Second, I implemented this interface in my Application's class: 其次,我在应用程序的类中实现了此接口:

public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{@Overridepublic void onCreate() {super.onCreate();           }@Overridepublic void onActivityStopped(Activity activity) {Log.i("Tracking Activity Stopped", activity.getLocalClassName());}@Overridepublic void onActivityStarted(Activity activity) {Log.i("Tracking Activity Started", activity.getLocalClassName());}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());}@Overridepublic void onActivityResumed(Activity activity) {Log.i("Tracking Activity Resumed", activity.getLocalClassName());}@Overridepublic void onActivityPaused(Activity activity) {Log.i("Tracking Activity Paused", activity.getLocalClassName());}@Overridepublic void onActivityDestroyed(Activity activity) {Log.i("Tracking Activity Destroyed", activity.getLocalClassName());}@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {Log.i("Tracking Activity Created", activity.getLocalClassName());}
}

Third, I'm creating a class that extends from SherlockActivity: 第三,我正在创建一个继承自SherlockActivity的类:

public class MySherlockActivity extends SherlockActivity {protected MyApplication nMyApplication;protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);nMyApplication = (MyApplication) getApplication();nMyApplication.onActivityCreated(this, savedInstanceState);}protected void onResume() {// TODO Auto-generated method stubnMyApplication.onActivityResumed(this);super.onResume();}@Overrideprotected void onPause() {// TODO Auto-generated method stubnMyApplication.onActivityPaused(this);super.onPause();}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubnMyApplication.onActivityDestroyed(this);super.onDestroy();}@Overrideprotected void onStart() {nMyApplication.onActivityStarted(this);super.onStart();}@Overrideprotected void onStop() {nMyApplication.onActivityStopped(this);super.onStop();}@Overrideprotected void onSaveInstanceState(Bundle outState) {nMyApplication.onActivitySaveInstanceState(this, outState);super.onSaveInstanceState(outState);}
}

Fourth, all class that extend from SherlockActivity, I replaced for MySherlockActivity: 第四,所有从SherlockActivity扩展的类,我都替换为MySherlockActivity:

public class MainActivity extends MySherlockActivity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);}}

Now, in the logcat you will see the logs programmed in the Interface implementation made in MyApplication. 现在,在logcat中,您将看到My​​Application中实现的Interface实现中编程的日志。


#6楼

I would like to recommend you to use another way to do this. 我建议您使用另一种方法来执行此操作。

I guess you want to show start up screen while the program is starting, if it is already running in backend, don't show it. 我想您想在程序启动时显示启动屏幕,如果它已经在后端运行,请不要显示它。

Your application can continuously write current time to a specific file. 您的应用程序可以将当前时间连续写入特定文件。 While your application is starting, check the last timestamp, if current_time-last_time>the time range your specified for writing the latest time, it means your application is stopped, either killed by system or user himself. 在您的应用程序启动时,请检查最后一个时间戳,如果current_time-last_time>您为写入最新时间而指定的时间范围,则意味着您的应用程序已停止,已被系统或用户杀死。

检查Android应用程序是否在后台运行相关推荐

  1. Android按返回键程序仍在后台运行,并未完全退出和销毁,类似微信QQ等退出方式的实现-- moveTaskToBack

    最近做的Android项目提了一个小的需求: 按了返回键之后,要像微信和QQ那样,程序仍在后台运行,并未完全退出和销毁,下次进来仍然在之前那个页面. 网上找到了解决方案,也很简单:其实就是重写按返回键 ...

  2. 如何在Android应用程序中实现后台服务?

    在Android应用程序中实现后台服务,可以通过继承Service类来实现.下面是一个简单的示例代码: 首先,在AndroidManifest.xml文件中注册服务: <manifest xml ...

  3. linux程序已经在后台运行冻结了_如何使程序在Linux后台运行

    经常在Linux上面运行程序都有这样的体验: 某个程序运行的时候,会产生大量的log(提示)信息,但实际上我们只想让它跑一下而已,log暂时不需要或者后面才有需要. 同时run多个相同或者不同程序的时 ...

  4. 华为怎么关Android,华为手机怎么关闭后台运行程序 华为手机关闭后台运行程序方法...

    初次使用华为手机的朋友注意了,华为手机关闭程序时,容易忘记从后台关闭.这样就会导致手机后台运行程序越来越多,手机使用变得越来越慢.那么怎么操作才能从后台上关闭程序呢? 华为手机关闭后台运行程序方法 这 ...

  5. android中如何实现蓝牙后台运行,Android实现的简单蓝牙程序示例

    本文实例讲述了Android实现的简单蓝牙程序.分享给大家供大家参考,具体如下: 我将在这篇文章中介绍了的Android蓝牙程序.这个程序就是将实现把手机变做电脑PPT播放的遥控器:用音量加和音量减键 ...

  6. 如何让android的service一直在后台运行

    1. 把service和activity分开,让service开机启动.设置一个broadcast receiver接受开机信号, 使用RECEIVE_BOOT_COMPLETED的permissio ...

  7. 安卓9 怎么运行老程序_这些安卓应用程序一直在后台运行,即使您关了它

    广告客户可能会违反Google的规定,正在收集可帮助他们摆脱Android隐私功能的信息. 有些应用可能会跟踪您的活动,即使您告诉他们忘记过去.你无能为力. 根据国际计算机科学研究所的研究,大约17, ...

  8. 让PHP程序永远在后台运行

    PHP里有个函数很有用.这是在最近的开发中才逐渐用到的. int ignore_user_abort ( [bool setting] ) 这个函数的作用是指示服务器端在远程客户端关闭连接后是否继续执 ...

  9. linux程序已经在后台运行冻结了_Linux 让程序在后台执行

    有些程序我们在打开时,会一直占用我们的终端,而且终端还不能关掉,所以这时候我们就需要让程序在后台运行. 1.命令:nohup nohup python -u run.py > run.log 2 ...

最新文章

  1. UIButton 的不同设置和UITextField 的默认值(修改默认值)
  2. AWR报告中Top 10 Foreground Events存在”reliable message”等待事件的处理办法
  3. (34)css光标属性cursor
  4. Codeforces | CF1029F 【Multicolored Markers】
  5. 今天学得有点多——end用法
  6. Mac电脑共享“公共文件夹”以外的文件夹的设置教程
  7. 使用bootstrap-table简化CRUD
  8. 怎样写 Linux LCD 驱动程序
  9. Water Tree CodeForces 343D 树链剖分+线段树
  10. 利用IP纯真数据库查询地址
  11. 英特尔推出SD卡巨细电脑 配Atom处理器
  12. -D指定db登陆失败ERROR 1044 (42000): Access denied for user ‘lzldb‘@‘%‘ to database ‘lzldb‘
  13. 设计一个以1秒频率闪烁的LED灯(亮灭各500ms)
  14. 功能性4G工业路由器该如何选择
  15. 华硕ROG|玩家国度 魔霸7Plus G713PV win11原厂系统 带ASUS Recovery
  16. 泪奔,我再一次愿意相信地久天长
  17. DS18B20测量温度
  18. UVA 12325 Zombie's Treasure Chest
  19. Python的format用法详解
  20. root 无法修改文件权限

热门文章

  1. 应用内存onLowMemory onTrimMemory优化
  2. android setContentView()
  3. IOS开发笔记15-自定义类
  4. 从源码角度分析MapReduce的reduce流程
  5. RandomAccessFile学习笔记
  6. 图片加载利器Picasso 解析
  7. iOS架构-静态库.framework之依赖第三方库(7)
  8. html5插件教程,HTML5教程 | HTML5 time元素
  9. codeforces193B
  10. codeforces708C