安卓利用判斷APP是否在後臺運行(ActivityLifecycleCallbacks)

在開發的時候,我們時常有這樣一個需求:判斷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中按照該思路實現即可。
源碼請戳這裏:源碼源碼QQ吹水羣:552123831
歡迎大家來吹水和關注的微信公衆號:哦哦猿

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章