Android 監聽APP進入後台或切換到前台方案對比

來源:互聯網
上載者:User

標籤:日誌統計   str   自身   run   作用   對比分析   rac   消費   資料   

在我們開發的過程中,經常會遇到需要我們判斷app進入後台,或者切換到前台的情況。比如我們想判斷app切換到前台時,顯示一個解鎖介面,要求使用者輸入解鎖密碼才能繼續進行操作;我們想判斷app切換到後台,記錄一下log;或者當使用者切換回前台時,我們想重新整理一下頁面的資料等等......

android裡面監聽app前背景方案很多(這還是得歸根於安卓提供了豐富的api和強大的架構支撐,呵呵~),比如可以通過ActivityManager提供的getRunningAppProcesses()擷取系統當前啟動並執行app,從而判斷app是否處於前台。或者通過監聽點擊Home鍵,判斷app是否回到了後台。下面將針對筆者已知的幾種方案,進行對比分析。

方案一:利用ActivityManager的RunningAppProcessInfo類
ActivityManager在整個系統裡面起著非常重要的作用,主要為系統中運行著的activity互動提供介面,其中RunningAppProcessInfo類則封裝了正在運行著的進程資訊,當然也包含了正在啟動並執行app的包名,因此我們可以activitymanager.getRunningAppProcesses()擷取當前啟動並執行app列表,對比自身的包名,來判斷本身app是否處於前台運行。

這打斷一下,ActivityManager架構是Android系統十分重要的一部分,在以後有時間,筆者會好好學習整理ActivityManager架構的分析。

回到這裡,下面給出部分關鍵代碼。

 /**     * App前後台狀態     */    public boolean isForeground = false;    @Override    protected void onResume() {        ......        if (isForeground == false) {            //由後台切換到前台            isForeground = true;        }    }     @Override    protected void onPause() {        ......        if (!isAppOnForeground()) {            //由前台切換到後台            isForeground = false;        }    }    /**     * 判斷app是否處於前台     *     * @return     */    public boolean isAppOnForeground() {         ActivityManager activityManager = (ActivityManager) getApplicationContext()                .getSystemService(Context.ACTIVITY_SERVICE);        String packageName = getApplicationContext().getPackageName();        /**         * 擷取Android裝置中所有正在啟動並執行App         */        List<RunningAppProcessInfo> appProcesses = activityManager                .getRunningAppProcesses();        if (appProcesses == null)            return false;         for (RunningAppProcessInfo appProcess : appProcesses) {            // The name of the process that this object is associated with.            if (appProcess.processName.equals(packageName)                    && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {                return true;            }        }         return false;    }

小結:通過ActivityManager來擷取當前啟動並執行app列表,然後判斷我們的app是否處於前台,能基本達到我們的預期需求。但如果將上面代碼放到每一個activity,或者activity基類裡面,這消耗還是挺大的。而且而且,ActivityManager通過.getRunningAppProcesses()擷取當前運行列表這個方法,在5.0以後已經被deprecated掉了....(心中萬馬奔騰...)

 

方案二:監聽Home鍵點擊

說起home鍵的監聽,也算是android裡面的一個梗。這看上去簡單的功能,實際上實現起來卻十分的曲折,這跟android系統的設計有很大的關係。當home鍵被點擊的時候,會發出一個系統廣播,在系統收到這個廣播以後,會在framework層做一系列操作將當前的app退到後台,然後把事件消費掉不傳給應用程式層,所以這時候 onKeyDown事件也接收不到了..用官方的解釋就是——“Home key. This key is handled by the framework and is never delivered to applications.”。實際上這也是為了安全性的考慮,不然每家的app都監聽home鍵,然後禁掉響應,不都成了流氓軟體了。

官方不支援,可是這難不到我們萬能的攻城獅們的,畢竟有很多想我們正規的開發人員,還是需要監聽home鍵來做一些如寫日誌之類的操作的。網上Google百度會有很多類似的解決方案,在這裡就不展開了。(不過這裡可以推薦一下)

小結:我們能監聽到home鍵點擊,當然就知道app處於前台還是後台了。但畢竟這個方案是基於官方不支援的前提下的,而且home鍵的監聽在很多裝置都會有相容性的問題,因此我們不大推薦這樣做。

方案三:利用ActivityLifecycleCallbacks監聽所有activity的生命週期

通過監聽所有activity的onStart、onStop調用,然後統計當前是不是所有的activity都調用了onStop,確實可以判斷app處於了後台,不過讓我們重寫每一個activity的onStop,並加這段奇怪的代碼,實在不大優雅,即使在activity基類裡面統一寫,那天如果忘了或者不需要繼承基類的activity,就不大好了。

因此,這裡推薦一個新的介面ActivityLifecycleCallbacks,說新也不新,其實早在API 14 (android 4.0)就已經推出了。ActivityLifecycleCallbacks介面在Application類裡面,因此需要我們自己繼承Application,自訂一個MyApplication,然後註冊介面。ActivityLifecycleCallbacks為application提供了對所有activity生命週期的監聽,因此我們通過重寫ActivityLifecycleCallbacks的onActivityStarted和onActivityStopped方法,定義一個變數,來統計當前有幾個activity處於前台。

 

  /**     * 當前Acitity個數     */    private int activityAount = 0;        @Override    public void onCreate() {        ......        registerActivityLifecycleCallbacks(activityLifecycleCallbacks);        ......    }     /**     * Activity 生命週期監聽,用於監控app前後台狀態切換     */    ActivityLifecycleCallbacks activityLifecycleCallbacks = new ActivityLifecycleCallbacks() {        @Override        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {        }         @Override        public void onActivityStarted(Activity activity) {//            if (activityAount == 0) {//                //app回到前台//                isForeground = true;//            }            activityAount++;        }         @Override        public void onActivityResumed(Activity activity) {        }        @Override        public void onActivityPaused(Activity activity) {        }         @Override        public void onActivityStopped(Activity activity) {            activityAount--;            if (activityAount == 0) {                isForeground = false;            }        }         @Override        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {        }        @Override        public void onActivityDestroyed(Activity activity) {        }    };

以上代碼寫在MyApplication裡面。怎麼樣,是不是很簡單快捷!而且準確無誤。

總結:
1、利用ActivityManager的RunningAppProcessInfo類,直接粗暴,官方摒棄,不推薦;
2、監聽Home鍵點擊,官方不支援,相容性差,不穩定,不推薦;
3、利用ActivityLifecycleCallbacks監聽所有activity的生命週期,官方指定飲品,哦,不對,官方指定介面,大力推薦!我們舉一反三,利用ActivityLifecycleCallbacks監聽,我們還能控制我們的activity堆棧,甚至還可以在裡面做日誌統計...想想還是很強大的。

PS:雖則利用ActivityLifecycleCallbacks介面監聽的方案最優,但這畢竟是4.0以後的產品,因此對於4.0以下的,可以考慮增加方案一判斷。

Android 監聽APP進入後台或切換到前台方案對比

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.