判斷Android app退後臺、進前臺

在某些特定的場景下,我們需要判斷App是否進入後臺運行狀態。然後根據App處在前臺/後臺分別進行不同的操作行爲。我們可以通過Activity的生命週期來,實現這一需求。
關於生命週期,我們可以分類爲三個類別:

1:entire lifetime(完整生命週期)
onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy.
2:visible lifetime(可見生命週期)
onStart -> onResume -> onPause -> onStop
3:foreground lifetime(前臺生命週期)
onResume -> onPause

根據上面,當應用處於前臺,當前Activity一定調用了onResume方法,而應用進入後臺時,一定會調用onPause方法。根據這個原理,我們利用Activity生命週期來判斷應用的前後臺運行狀態。很輕鬆的獲取了各種情境下應用的前後臺狀態變換。

上代碼:

package mo.yumf.com.myviews;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 在Application類中監聽App處於前臺和後臺
 */

public class ForegroundCallbacks implements Application.ActivityLifecycleCallbacks {

    public static final long CHECK_DELAY = 500;

    public static final String TAG = ForegroundCallbacks.class.getName();

    public interface Listener {
        void onBecameForeground();
        void onBecameBackground();
    }

    private static ForegroundCallbacks instance;

    private boolean foreground = false, paused = true;

    private Handler handler = new Handler();

    private List<Listener> listeners = new CopyOnWriteArrayList<>();

    private Runnable check;

    public static ForegroundCallbacks init(Application application){
        if (instance == null) {
            instance = new ForegroundCallbacks();
            application.registerActivityLifecycleCallbacks(instance);
        }
        return instance;
    }
    public static ForegroundCallbacks get(Application application){
        if (instance == null) {
            init(application);
        }
        return instance;
    }
    public static ForegroundCallbacks get(Context ctx){
        if (instance == null) {
            Context appCtx = ctx.getApplicationContext();
            if (appCtx instanceof Application) {
                init((Application)appCtx);
            }
            throw new IllegalStateException(
                    "Foreground is not initialised and " +
                            "cannot obtain the Application object");
        }
        return instance;
    }
    public static ForegroundCallbacks get(){
        if (instance == null) {
            throw new IllegalStateException(
                    "Foreground is not initialised - invoke " +
                            "at least once with parameterised init/get");
        }
        return instance;
    }
    public boolean isForeground(){
        return foreground;
    }
    public boolean isBackground(){
        return !foreground;
    }
    public void addListener(Listener listener){
        listeners.add(listener);
    }
    public void removeListener(Listener listener){
        listeners.remove(listener);
    }
    @Override
    public void onActivityResumed(Activity activity) {
        paused = false;
        boolean wasBackground = !foreground;
        foreground = true;
        if (check != null)
            handler.removeCallbacks(check);
        if (wasBackground){
            Log.e("yumf","went foreground");
            for (Listener l : listeners) {
                try {
                    l.onBecameForeground();
                } catch (Exception exc) {
                    Log.e("yumf","Listener threw exception!");
                }
            }
        } else {
            Log.e("yumf","still foreground");
        }
    }
    @Override
    public void onActivityPaused(Activity activity) {
        paused = true;
        if (check != null)
            handler.removeCallbacks(check);
        handler.postDelayed(check = new Runnable(){
            @Override
            public void run() {
                if (foreground && paused) {
                    foreground = false;
                    Log.e("yumf","went background");
                    for (Listener l : listeners) {
                        try {
                            l.onBecameBackground();
                        } catch (Exception exc) {
                            Log.e("yumf","Listener threw exception!", exc);
                        }
                    }
                } else {
                    Log.e("yumf","still foreground");
                }
            }
        }, CHECK_DELAY);
    }
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
    @Override
    public void onActivityStarted(Activity activity) {}
    @Override
    public void onActivityStopped(Activity activity) {}
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
    @Override
    public void onActivityDestroyed(Activity activity) {}
}

在Application類中:

public class MyApplication extends Application {
    private int mCount;
    @Override
    public void onCreate() {
        super.onCreate();

        ForegroundCallbacks callbacks = ForegroundCallbacks.get(this);
        callbacks.addListener(new ForegroundCallbacks.Listener() {
            @Override
            public void onBecameForeground() {
                Log.i("yumf","====foreground");
            }

            @Override
            public void onBecameBackground() {
                Log.i("yumf","====background");
            }
        });
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章