前言
先梳理下“前台”的概念。当App对用户可见,并且用户可以与App直接进行交互的时候,此时,我们说App处于前台;而当我们按下Home键回到桌面,此时则App处于“后台”,通过点击图标或者多任务再次进入App,App再次进入前台。有些时候,我们需要对App的前后台的状态改变进行监听,来进行一些操作,比如一些服务的重连等等。
进入正题
在Application
类中存在一个registerActivityLifecycleCallbacks
方法,该方法接受一个ActivityLifecycleCallbacks
接口,传入一个匿名内部类后是这样:
registerActivityLifecycleCallbacks(new 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) {
}
});
我们看到了Activity
中的各个熟悉方法的回调。也就是我们注册该接口之后App中任何Activity
的生命周期回调都可以在这里拿到,当前,前提是不能注释Activity
对应生命周期中的super.onxxx()
方法。
可能这么多回调会使代码变得混乱,在大多数时候,我们只需要关心其中的一两个方法。写一个适配类如下:
public class ActivityLifecycleCallbacksAdapter implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@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 bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
什么也不干,只是实现它而已,但是这样做了之后,在调用registerActivityLifecycleCallbacks
方法时,我们可以传入我们的适配类,然后重写关注的方法即可。
此时,回到我们本文的探讨,我们知道,当我们的App回到后台,所有的Acticity
会依次执行->onPause()
->
onStop()
方法。而当回到前台的时候,所有的Activity
会执行onStart()
->onResume()
方法。我们在Application
引入一个变量,负责保存当前处于‘苏醒’状态的Activity
的个数,同时在上面的回调中不断更新这个变量的值,根据他的值推断出前后台的切换。
// 监听切换到前台
private int rusumeActivityCount = 0;
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacksAdapter(){
@Override
public void onActivityStarted(Activity activity) {
if (rusumeActivityCount++==0){
// 执行切换到前台的逻辑
}
}
@Override
public void onActivityStopped(Activity activity) {
if(--rusumeActivityCount==0){
// 执行切换到后台的逻辑
}
}
});
rusumeActivityCount
初始为0,在onActivityStarted
中自增,并且自增之前判断一下自己的值,如果是0,则表示是第一次启动或者重新回到前台;在rusumeActivityCount
自减,如果等于0
,则表示App即将进入后台。
我们可以写一个工具类方便使用,写法如下:
public class AppStateTracker {
public static final int STATE_FOREGROUND = 0;
public static final int STATE_BACKGROUND = 1;
private static int currentState;
public static int getCurrentState() {
return currentState;
}
public interface AppStateChangeListener {
void appTurnIntoForeground();
void appTurnIntoBackGround();
}
public static void track(Application application, final AppStateChangeListener appStateChangeListener){
application.registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks(){
private int resumeActivityCount = 0;
@Override
public void onActivityStarted(Activity activity) {
if (resumeActivityCount==0){
currentState = STATE_FOREGROUND;
appStateChangeListener.appTurnIntoForeground();
}
resumeActivityCount++;
}
@Override
public void onActivityStopped(Activity activity) {
resumeActivityCount--;
if (resumeActivityCount==0){
currentState = STATE_BACKGROUND;
appStateChangeListener.appTurnIntoBackGround();
}
}
});
}
private static class SimpleActivityLifecycleCallbacks implements Application
.ActivityLifecycleCallbacks{
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@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 bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
}
在Application的onCreate()方法中调用即可:
AppStateTracker.track(this, new AppStateTracker.AppStateChangeListener() {
@Override
public void appTurnIntoForeground() {
// 处理app到前台的逻辑
}
@Override
public void appTurnIntoBackGround() {
// app处理到到后台的逻辑
}
});
如果其它地方需要监听前后台状态处理一些逻辑,可以利用EventBus之类的组件在AppStateChangeListener
的回调中发出对应的事件即可。
结论
经过自测,在不考虑极端情况下,该方式能准确监听前后台切换状态的改变。并且该方式通过在Application
中注册接口回调的方式来监听前后台切换。对Activity
无侵入,不需要依赖繁琐的系统服务来判断,代码较少,容易理解,算得上是一种优雅的方式了。