preface
Let’s start with the concept of the front desk. When the App is visible to the user and the user can interact directly with the App, the App is said to be in the foreground. When we press the Home button to return to the desktop, the App will be in the “background”. We can enter the App again by clicking the icon or multitasking, and the App will enter the foreground again. Sometimes, we need to monitor the state changes in the front and back of the App to perform some operations, such as reconnection of some services and so on.
Get into the business
Exist in the Application class a registerActivityLifecycleCallbacks method, this method accepts a ActivityLifecycleCallbacks interface, was introduced into after an anonymous inner class is like this:
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) {
}
});
Copy the code
We see callbacks to various familiar methods in the Activity. That is, after we register the interface, any Activity lifecycle callbacks in the App can be retrieved here, as long as we don’t comment out the super.onxxx() method in the Activity lifecycle.
It’s possible that so many callbacks can clutter up the code, and most of the time, we only need to care about one or two of them. Write an adaptation class as follows:
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) { } }Copy the code
Do nothing, just do it, but do so after the call registerActivityLifecycleCallbacks method, we can pass in our adapter classes, then rewrite attention method.
At this point, returning to our discussion in this article, we know that when our App returns to the background, all acElasticity will execute ->onPause()-> onStop(). When returned to the foreground, all activities execute the onStart() ->onResume() method. We introduce a variable in the Application that holds the number of activities currently in the ‘awake’ state, and we update the value of this variable in the above callback to infer the switch from its value.
Private int rusumeActivityCount = 0; registerActivityLifecycleCallbacks(newActivityLifecycleCallbacksAdapter(){
@Override
public void onActivityStarted(Activity activity) {
if(rusumeActivityCount++==0){// perform the logic to switch to the foreground}} @override public void onActivityStopped(Activity Activity){if(--rusumeActivityCount==0){// Execute the logic to switch to background}}});Copy the code
RusumeActivityCount starts at 0, increments in onActivityStarted, and determines its value before incrementing. If it is 0, it is started for the first time or is back in the foreground. At rusumeActivityCount decrement, if it equals 0, the App is about to go into the background.
We can write a utility class for easy use as follows:
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) { } } }Copy the code
Call onCreate() from Application:
AppStateTracker.track(this, new AppStateTracker.AppStateChangeListener() {
@Override
public void appTurnIntoForeground} @override public void Override public void Override public void OverrideappTurnIntoBackGround() {// app processing to the background logic}});Copy the code
If you need to listen for the front and back state to handle some logic elsewhere, you can use a component like EventBus to emit the corresponding event in the AppStateChangeListener callback.
conclusion
Through self-test, this method can accurately monitor the change of front and background switching state without considering extreme circumstances. And it listens for front and back transitions by registering interface callbacks in the Application. No intrusion on the Activity, no need to rely on tedious system services to judge, less code, easy to understand, is an elegant way.