判斷App是否在後臺運行

 

在一些場景中,常常會須要判斷App是否在後臺運行,好比是否顯示解鎖界面,收到新消息是否顯示Notification等。需求多是多樣化的,但所依仗的原理是相通的,今天Stay打算說說這些需求的最優解。面試

固然,Stay確定不會說去for loop判斷當前runningProcess或者runningTasks。好比:oop

這樣性能

或者這樣測試

這種方法調用起來感受就像是在用Windows系統裏的任務管理器,真是讓人蛋疼。咱們暫且不去計較性能問題,就說爲啥Android連個像樣的API都不給我,着實讓人鬱悶。spa

若是帶着這樣的質疑去調研,你會發現還真有其餘方式來實現。blog

Android在SDK 14的時候提供了一個Callback。ActivityLifecycleCallbacks,你能夠經過這個Callback拿到App全部Activity的生命週期回調。看圖:生命週期

這個Callback寫在Application裏的,你能夠在Application初始化的時候來註冊。咱們能夠寫個單例類來cache這些status。這裏我叫它AppStatusTracker。在Application的onCreate()裏讓AppStatusTracker註冊ActivityLifecycleCallbacks。ci

拿到這些Callback有什麼用呢,我怎麼能知道App是否在前臺運行呢。 element


別急,咱們先來講說Activity的生命週期。這是面試時必問題,雖然有官方答案,但真正理解生命週期,並靈活運用的很少。rem

咱們來設想下若是Activity調用了onResume(),那麼這個Activity確定是可見的,也就是運行在前臺的。若是調用了onPause(),且沒有Activity來調用onResume(),那麼App要跑到後臺去了。至於它是點了home鍵仍是back鍵我都無論。

經過這樣的判斷,咱們來利用ActivityLifecycleCallbacks回調的onActivityResumed()和onActivityPaused()方法來計數,若是隻有一個activityCount,那麼當前App在前臺,若是木有activityCount,它就在後臺。

好了,就這麼愉快的解決了,不再用for loop了。可是很快你會發現,這裏有個延時,會致使判斷不許確。

咱們假設有兩個Activities,一個A,一個B,從A跳轉到B,生命週期怎麼走的? A.onPause() -> B.onResume() 對應到ActivityLifecycleCallbacks裏是onActivityPaused(A) -> onActivityResumed(B),剛纔咱們說的計數resumeCount,在onActivityPaused()裏--,在onActivityResumed()裏++, 根據這樣的判斷會有個短暫的間隔,也就是在A的onPause()到B的onResume()之間,App是運行在後臺的,這樣邏輯確定就不對了。

那如何解決問題呢?若是你打印過生命週期的哪些方法,你會發現是Activity間切換的步驟是這樣的: 


從WelcomeActivity跳轉到GestureActivity。(這裏只說onStart, onResume這些回調 )
A.onPause() -> B.onStart() -> B.onResume() -> A.onStop()

我估摸着60%的同窗都沒想過Activities之間切換的生命週期是什麼樣的。

 

經過這些回調咱們能夠將這個計數放在onStart()和onStop()中去,這樣就不會存在那個短暫間隔。activityCount==1,那麼就是前臺,activityCount==0,那就是後臺。這樣判斷很很簡單了吧。

如今再說,什麼狀況下來顯示手勢解鎖界面。 
個人需求是當用戶鎖屏後再解鎖或者切換到後臺10分鐘後顯示手勢解鎖界面。 
咱們拆分下需求,先說鎖屏,解鎖。

這個是有BroadCastReciever來接收的,註冊下就能夠了,每次收到鎖屏ACTION_SCREEN_OFF的action時,將AppStatusTracker裏的isScreenOff設置爲true。 
當onActivityResumed()被調用時再將isScreenOff設爲false。

再說切換到後臺10分鐘後顯示手勢解鎖。這個只須要在onActivityStop()時更新下lastBackgroudTimestamp就能夠了

核心代碼以下:

原理很簡單,可是涉及到的知識點很重要,你們能夠本身寫寫測試下,別總依賴別人的代碼,別人的類庫,技術實現很簡單,但需求的變體擴展有時候仍是須要本身來想辦法解決的。

相關文章
相關標籤/搜索