利用ActivityLifecycleCallbacks判断APP是否在后台运行

来源:互联网 发布:mac webpack 查看版本 编辑:程序博客网 时间:2024/05/21 06:47

在开发的时候,我们时常有这样一个需求:判断APP是否在后台运行?
常见的方式是这样的:

这里写图片描述

或者是这样的:

这里写图片描述

如上的这两种方式都可以满足我们的需求 。

但是这么做效率高么?不!请注意,这里是一个大写的
这很像我们平时用瘟到死操作系统去打开任务管理器的感觉;或者写了一个看上去金光闪闪,牛叉哄哄的for循环挨个遍历一遍。

我们可以不这么鲁莽么?我们可以换一种优雅的方式来实现这个功能么?我们可以用Android系统的API来实现么?可以!请注意,这里是一个大写的可以

Android在SDK 14提供了一个Callback即ActivityLifecycleCallbacks,通过这个Callback可拿到App所有Activity的生命周期回调

这里写图片描述

从这个接口里的几个方法名你大概猜到了:在这个回调中可以监测App中所有Activity的生命周期,它们都赤果果地站在你面前了。嗯哼,是不是有一种类似的感觉:公司妹子们的手机号都搞到手了?都到这份上了,下面该干什么了……….

当然是看看这个回调怎么用,不要想歪了…….

首先自定义一个Application在其onCreate( )方法中注册ActivityLifecycleCallbacks.

public class MyApplication extends Application {    private static MyApplication mApplicationInstance;    private ActivityLifecycleCallbacksImpl mActivityLifecycleCallbacksImpl;    @Override    public void onCreate() {        super.onCreate();        mApplicationInstance=new MyApplication();        mActivityLifecycleCallbacksImpl=new ActivityLifecycleCallbacksImpl();        this.registerActivityLifecycleCallbacks(mActivityLifecycleCallbacksImpl);    }    public static MyApplication getInstance() {        if (null==mApplicationInstance) {            mApplicationInstance=new MyApplication();        }        return mApplicationInstance;    }    private class ActivityLifecycleCallbacksImpl implements ActivityLifecycleCallbacks{        @Override        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {        }        @Override        public void onActivityStarted(Activity activity) {        }        @Override        public void onActivityResumed(Activity activity) {        }        @Override        public void onActivityPaused(Activity activity) {        }        @Override        public void onActivityStopped(Activity activity) {        }        @Override        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {        }        @Override        public void onActivityDestroyed(Activity activity) {        }    }}


这个时候我们就要考虑了:怎么判断APP是否运行在后台?
从Activity的生命周期我们可知:
Activity调用onResume(),那么该Activity是可见的,即它在前台。
Activity调用onPause(),那么该Activity就到了后台。
顺着这个思路往下走,我们可以在ActivityLifecycleCallbacks中利用一个计数器activityCounter来判断是否有Activity运行在前台。
1 在onActivityResumed()方法中使activityCounter+1
2 在onActivityPaused()方法使activityCounter-1

所以:
当activityCounter=0的时候我们可以判定APP运行在后台
当activityCounter=1的时候我们可以判定APP运行在前台

这么做是不是觉得挺nice的?嗯哼。
这么做有瑕疵么?有遗漏的地方么?
我们来看这么一种常见的场景:
假设存在两个界面Activity A和Activity B
在Activity A启动后activityCounter=1;这个是没有疑问的。
在某一时刻App需要从Activity A跳转到Activity B,此时这两个Activity的生命周期如下:
A.onPause()->B.onCreate()->B.onStart()-> B.onResume()-> A.onStop()
假若按照我们的处理方式:
此时Activity A会执行到onPause(),那么在ActivityLifecycleCallbacks中使activityCounter-1,此时activityCounter=0;表示该APP运行在后台.
这当然是错的:两个界面切换的过程中APP怎么可能是运行在后台的呢?
我们错在哪里了?!?
我们平常不就是习惯性地在onPause()和onResume()做操作么?
是的,平常那么做没啥做,因为那是单个的Activity,但是这里涉及到了两个Activity的跳转。我们错就错在惯性思维,错在了想当然。

当我们冷静一下,回头再瞅瞅两个Activity跳转时两者的生命周期就可发现,只需很小的修改就可以纠正这个问题:
1 在onActivityStarted()中对于activityCounter+1
2 在onActivityStopped()中对于activityCounter-1
这样就解决了刚才的问题。

ActivityLifecycleCallbacks除了可以帮助我们判断App是否运行在后台?还能帮我们做什么呢?有时候项目是不是要求:退出应用时关闭所有的Activity呢?嗯哼,利用ActivityLifecycleCallbacks也可以做到.我们可以采用一个LinkedList管理应用中的界面
1 在ActivityLifecycleCallbacks的onActivityCreated()将Activity添加到 LinkedList中
2 在ActivityLifecycleCallbacks的onActivityDestroyed()将Activity从LinkedList中移除
3 退出应用时销毁LinkedList中所有Activity

在最前面我们也提到了ActivityLifecycleCallbacks是在API 14及其以上才有的。那么在Android4.0以下又可以怎么做呢?
其实不难,我们在应用的BaseActivity中按照该思路实现即可。


备注说明:
1 源码下载
2 大家可加QQ群: 183899857讨论技术问题
3 亦可在博文下方留言或者评论

7 0
原创粉丝点击