在开发的时候,我们时常有这样一个需求:判断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 亦可在博文下方留言或者评论