为了账号安全,请及时绑定邮箱和手机立即绑定

检查Android应用程序是否在后台运行

检查Android应用程序是否在后台运行

holdtom 2019-06-01 10:52:12
检查Android应用程序是否在后台运行根据背景,我的意思是用户当前看不到应用程序的任何活动?
查看完整描述

3 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

关键是使用ActivityLifecycleCallbacks(请注意,这需要AndroidAPI级别14(Android4.0)。只需检查已停止活动的数量是否等于已启动活动的数量。如果他们是平等的,你的申请是背靠背的。如果有更多已启动的活动,您的应用程序仍然是可见的。如果恢复的活动多于暂停的活动,您的应用程序不仅是可见的,而且还处于前台。有三个主要的状态,你的活动可以在:可见和在前景,可见但不在前景,不可见和在前景(即在背景中)。

这个方法真正好的地方在于它没有异步问题getRunningTasks()是的,但你也不必修改每一个Activity在您的应用程序中设置/取消设置onResumed()/onPaused()..它只是几行自包含的代码,在整个应用程序中都能工作。此外,也不需要任何时髦的权限。

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;

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
    }

    @Override
    public void onActivityResumed(Activity activity) {
        ++resumed;
    }

    @Override
    public void onActivityPaused(Activity activity) {
        ++paused;
        android.util.Log.w("test", "application is in foreground: " + (resumed > paused));
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }

    @Override
    public void onActivityStarted(Activity activity) {
        ++started;
    }

    @Override
    public 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 four
    private static int resumed;
    private static int paused;
    private static int started;
    private static int stopped;

    // And these two public static functions
    public static boolean isApplicationVisible() {
        return started > stopped;
    }

    public static boolean isApplicationInForeground() {
        return resumed > paused;
    }
    */}

java:

// Don't forget to add it to your manifest by doing// <application android:name="your.package.MyApplication" ...public class MyApplication extends Application {
    @Override
    public 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已经就这个方法提出了一些很好的问题,我想在这个答案中为每个人回答:

onStop()不是在内存不足的情况下调用;这是一个问题吗?

否。为onStop()说:

请注意,在内存不足的情况下,这个方法可能永远不会被调用,因为系统没有足够的内存来使您的活动的进程在其onPace()方法被调用之后继续运行。

这里的关键是“保持你的活动进程运行.“如果达到这种低内存状态,您的进程实际上就会被扼杀(而不仅仅是您的活动)。这意味着这种检查背景-Ness的方法仍然有效,因为:(A)如果进程被终止,也不能检查回滚;(B)如果进程再次启动(因为创建了新的活动),则成员变量(无论静态还是非静态)为MyLifecycleHandler将被重置为0.

这是否适用于配置更改?

默认情况下不。您必须显式设置configChanges=orientation|screensize (|在清单文件中处理配置更改,否则您的活动将被销毁和重新创建。如果不设置此值,则将按以下顺序调用活动的方法:onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume..正如您所看到的,没有重叠(通常,在两者之间切换时,两个活动非常简短地重叠,这就是这种回退检测方法的工作方式)。为了避免这种情况,你必须设置configChanges这样你的活动就不会被破坏。幸运的是,我不得不configChanges已经在我的所有项目中,因为我的整个活动在屏幕旋转/调整大小时被破坏是不可取的,所以我从未发现这是有问题的。(感谢dpimka在这件事上刷新了我的记忆并纠正了我!)

一份说明:

当我在这个答案中说“背景”时,我的意思是“你的应用程序不再可见”。Android活动可以是可见的,但在前景中却是不可见的(例如,如果有透明的通知覆盖)。这就是为什么我更新了这个答案来反映这一点。

重要的是要知道Android在切换活动时有一个奇怪的模糊时刻前景中什么都没有..因此,如果您在切换活动(在同一应用程序中)时检查应用程序是否位于前台,您将被告知您不在前台(即使您的应用程序仍然是活动应用程序,并且是可见的)。

您可以检查您的应用程序是否位于ActivityonPause()方法 super.onPause()..记住我刚才提到的奇怪的状态。

您可以检查您的应用程序在您的应用程序中是否可见(也就是说,它不在后台)。ActivityonStop()方法 super.onStop().


查看完整回答
反对 回复 2019-06-01
  • 3 回答
  • 0 关注
  • 984 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信