用onResume監(jiān)聽Application回到前臺

Android中的前臺就是指用戶可見哗蜈,后臺就是指用戶不可見前标。
對于Activity來說坠韩,可以通過生命周期,監(jiān)聽回到前臺炼列,或切到后臺的行為只搁。
但是對于Application來說,就很難監(jiān)控回到前臺還是切到后臺俭尖,因為Android任務(wù)棧的設(shè)計中氢惋,允許來自多個Application的Activity組成任務(wù)棧,所以無法通過Activity的生命周期稽犁,直接監(jiān)聽Application在前后臺的切換焰望。

針對Application在前后臺切換的監(jiān)聽,一般有兩種思路:

  1. RunningAppProcessInfo
    用RunningAppProcessInfo信息已亥,通過appProcess.processName和App的packageName對比熊赖,找到App所在的進程,通過進程的優(yōu)先級判斷是否是前臺進程虑椎。
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;  
                        }  
                } 
  1. 統(tǒng)計Activity的生命周期
    在Application中監(jiān)聽所有Activity的生命周期震鹉,通過統(tǒng)計活動Activity的數(shù)量進行判斷(代碼略)。

這兩種思路绣檬,其實都依賴Activity的生命周期足陨,需要在onStop中進行檢查嫂粟,在很多場景中也是好用的娇未。
但是,Activity并不總會執(zhí)行onStop星虹,如果打開的新Activity是透明背景零抬,或者是彈出框格式,舊Activity不會被遮擋宽涌,就不會執(zhí)行onStop平夜,對應(yīng)的也沒有onStart,如果這個新的Activity屬于其他Application卸亮,就無法監(jiān)聽到Application的前后臺切換了忽妒。

為了解決這個問題,我們基于第2個思路兼贸,進行了擴展段直,通過對整個生命周期的判斷,實現(xiàn)在onResume中溶诞,監(jiān)聽Application回到前臺的功能鸯檬。(目前還沒有辦法判斷退到后臺)

主要思路如下:
·在常規(guī)情況下,包括Home鍵返回桌面的情況下螺垢,思路2是好用的喧务。
·在舊Activity不被遮擋赖歌、不執(zhí)行onStop的情況下,滿足以下三個過濾條件的功茴,視為Application回到前臺:
1.執(zhí)行過onPause(說明有其他Activity遮蓋)
2.沒有在onStart中判定為回到前臺(避免在常規(guī)情況下庐冯,事件重復(fù))
3.不是第一次onResume(如果本App打開了新的Activity,也會先執(zhí)行一遍onPause坎穿,那么在Application級別肄扎,第一次進入onResume會被錯誤觸發(fā),導(dǎo)致判斷失靈赁酝,所以還需要判斷已經(jīng)執(zhí)行過至少一次onResume)
第三條跟兩個Activity的生命周期有關(guān)犯祠,其判斷邏輯如圖:


判斷不是第一次onResume

經(jīng)測試,該方法能有效監(jiān)聽Application回到前臺的事件酌呆。

我們把這個邏輯抽象為一個工具類衡载,代碼如下:

public class OnFrontUtil {
    private static final String TAG="OnFrontUtil";
    boolean isResumed = false;
    boolean isPaused = false;
    boolean isFront = false;
    int count=0;

    //因為需要統(tǒng)計Activity,所以用單例實現(xiàn)
    private volatile static OnFrontUtil instance;
    private OnFrontUtil(Application app, OnFrontCallback callback){
        registerOnFront(app,callback);
    }

    //只需要在初始化時被調(diào)用一次隙袁,所以修改了單例寫法痰娱,不再返回實例,只完成注冊監(jiān)聽
    public static void listenOnFront(Application app,OnFrontCallback callback){
        if(instance==null){
            synchronized (OnFrontUtil.class){
                if(instance==null){
                    instance=new OnFrontUtil(app,callback);
                }
            }
        }
    }

    //向調(diào)用者反饋回到前臺事件
    public interface OnFrontCallback{
        void onFront();
    }

    //通過監(jiān)聽和統(tǒng)計Activity生命周期菩收,判斷App是否來到前臺顯示
    private void registerOnFront(Application app,final OnFrontCallback callback){
        app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {
                isResumed = false;
            }

            @Override
            public void onActivityStarted(Activity activity) {
                count++;

                Log.i(TAG," started "+count);
                if(count==1){
                    Log.i(TAG," is front");
                    callback.onFront();
                    isFront = true;

                }

            }

            @Override
            public void onActivityResumed(Activity activity) {
                //1.有執(zhí)行過onPause
                //2.不是重復(fù)事件
                //3.不是第一次進入onResume
                if(isPaused&&!isFront&&isResumed){
                    if(count==1){
                        Log.i(TAG," is front");
                        callback.onFront();
                    }
                }
                isPaused = false;
                isResumed = true;
                isFront = false;
            }


            @Override
            public void onActivityPaused(Activity activity) {
                isPaused = true;
            }

            @Override
            public void onActivityStopped(Activity activity) {
                count--;

                Log.i(TAG," stopped "+count);
                if(count==0){
                    Log.i(TAG," is background");

                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
    }
}

使用該工具類的方式如下:

        OnFrontUtil.listenOnFront(this, new OnFrontUtil.OnFrontCallback() {
            @Override
            public void onFront() {
                //數(shù)據(jù)上報梨睁,App回到前臺

            }
        });

引用

如何判斷一個Android應(yīng)用程序轉(zhuǎn)到后臺并回到前臺

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市娜饵,隨后出現(xiàn)的幾起案子坡贺,更是在濱河造成了極大的恐慌,老刑警劉巖箱舞,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遍坟,死亡現(xiàn)場離奇詭異,居然都是意外死亡晴股,警方通過查閱死者的電腦和手機愿伴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來电湘,“玉大人隔节,你說我怎么就攤上這事〖徘海” “怎么了怎诫?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昧谊。 經(jīng)常有香客問我刽虹,道長,這世上最難降的妖魔是什么呢诬? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任涌哲,我火速辦了婚禮胖缤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘阀圾。我一直安慰自己哪廓,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布初烘。 她就那樣靜靜地躺著涡真,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肾筐。 梳的紋絲不亂的頭發(fā)上哆料,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音吗铐,去河邊找鬼东亦。 笑死,一個胖子當著我的面吹牛唬渗,可吹牛的內(nèi)容都是我干的典阵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼镊逝,長吁一口氣:“原來是場噩夢啊……” “哼壮啊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撑蒜,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤歹啼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后减江,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體染突,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年辈灼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片也榄。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡巡莹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出甜紫,到底是詐尸還是另有隱情降宅,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布囚霸,位于F島的核電站腰根,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拓型。R本人自食惡果不足惜额嘿,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一瘸恼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧册养,春花似錦东帅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坎炼,卻和暖如春愧膀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谣光。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工扇调, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抢肛。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓狼钮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捡絮。 傳聞我的和親對象是個殘疾皇子熬芜,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-androi...
    eddy_wiki閱讀 3,252評論 0 20
  • 為了面試福稳,為了高工資涎拉,廢話不多說,不定期更新。 1. Activity正常和異常情況下的生命周期分析的圆。 Activ...
    24K男閱讀 826評論 0 0
  • 本文出自 “阿敏其人” 簡書博客越妈,轉(zhuǎn)載或引用請注明出處季俩。 一、前言 Activity梅掠,安卓四大組件之一酌住。 每個 A...
    阿敏其人閱讀 9,080評論 8 88
  • 最近剛從舊公司離職,為面試在做準備阎抒,因為平時開發(fā)CV大法用得比較多酪我,很多基礎(chǔ)知識掌握得不是很牢靠以及很多工具框架只...
    黎清海閱讀 2,171評論 1 19
  • “現(xiàn)在,我來宣布第250屆諾爾文學(xué)獎的獲得者是……”且叁,“噔噔瞪……”我的心隨著舞臺四周傳來的強烈的節(jié)奏聲都哭,也強有力...
    半朽閱讀 1,637評論 24 46