Android中應(yīng)用前后臺切換監(jiān)聽的實現(xiàn)詳解
前言
最近在工作中遇到了這么一個需求:如何實現(xiàn) Android 應(yīng)用前后臺切換的監(jiān)聽?下面來一起看看詳細(xì)的介紹:
iOS 內(nèi)邊是可以實現(xiàn)的,AppDelegate 給了一個回調(diào)監(jiān)聽:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } }
我保留了系統(tǒng)注釋。一個iOS應(yīng)用周期,大概的流程是這樣的。
應(yīng)用從前臺進(jìn)入到后臺:
applicationWillResignActive() -> applicationDidEnterBackground()
應(yīng)用從后臺恢復(fù)到前臺:
applicationWillEnterForeground() -> applicationDidBecomeActive()
Android 中也存在 Application,但是并沒有提供前后臺切換的監(jiān)聽。
倒不如說,在 Android 中,壓根就沒有應(yīng)用前后臺的概念。
Android 中基本頁面單位是 Activity。
Activity 有自己的生命周期,但是 Application 卻沒有一個整體的生命周期。
我們可以通過監(jiān)聽 Activity 的生命周期,來模擬實現(xiàn)一個 Application 的生命周期。
Activity 的生命周期不在闡述,寫過 Android 的都應(yīng)該知道。
我們假設(shè)現(xiàn)在有兩個 Activity 分別是 A 和 B,A 是啟動頁面,那么生命周期回調(diào)是這樣的:(我們忽略掉一些不關(guān)心的回調(diào))
A 被啟動或者 A 進(jìn)入前臺
A.onStart() A.onResume()
從 A 跳轉(zhuǎn)到 B:
A.onPause() B.onStart() B.onResume() A.onStop()
從 B 返回 A:
B.onPause() A.onStart() A.onResume() B.onStop()
A 被關(guān)閉或者 A 進(jìn)入后臺
A.onPause() A.onStop()
注意上面兩個頁面回調(diào)的啟動順序。
onResume 和 onPause 是一組,兩個頁面之間是順序調(diào)用。
onStart 和 onStop 是一組,兩個頁面之間是交叉調(diào)用。
也就是說,A 啟動到 B,會先調(diào)用 B.onStart()
,然后再調(diào)用 A.onStop()
;而 B 返回 A 則是相反的,會先調(diào)用 A.onStart()
,然后再調(diào)用 B.onStop()
。
利用這個特性,我們可以做一個全局計數(shù)器,來記錄前臺頁面的數(shù)量,在所有 Activity.onStart()
中計數(shù)器 +1,在所有 Activity.onStop()
中計數(shù)器 -1。計數(shù)器數(shù)目大于0,說明應(yīng)用在前臺;計數(shù)器數(shù)目等于0,說明應(yīng)用在后臺。計數(shù)器從1變成0,說明應(yīng)用從前臺進(jìn)入后臺;計數(shù)器從0變成1,說明應(yīng)用從后臺進(jìn)入前臺。
有了思路,我們來實現(xiàn)。
Application 提供了一個監(jiān)聽器用于監(jiān)聽整個應(yīng)用中 Activity 聲明周期:Application.ActivityLifecycleCallbacks
。
這個監(jiān)聽器要求 API >= 14。對應(yīng) API < 14 的情況,可以通過編寫一個 BaseActivity,然后讓所有的 Activity 都集成這個類來實現(xiàn)整個應(yīng)用 Activity 聲明周期的監(jiān)聽,效果是相同的。
API >= 14,實現(xiàn)如下:
public class ApplicationListener implements Application.ActivityLifecycleCallbacks { private int foregroundCount = 0; // 位于前臺的 Activity 的數(shù)目 @Override public void onActivityStarted(final Activity activity) { if (foregroundCount <= 0) { // TODO 這里處理從后臺恢復(fù)到前臺的邏輯 } foregroundCount++; } @Override public void onActivityStopped(Activity activity) { foregroundCount--; if (foregroundCount <= 0) { // TODO 這里處理從前臺進(jìn)入到后臺的邏輯 } } /* * 下面回調(diào),我們都不需要 */ @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} @Override public void onActivityResumed(Activity activity) {} @Override public void onActivityPaused(Activity activity) {} @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} @Override public void onActivityDestroyed(Activity activity) {} }
我們在 Application 中注冊這個監(jiān)聽器來發(fā)揮效果:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(new ApplicationListener()); } }
對于 API < 14 的情況,BaseActivity 實現(xiàn)如下:
public class BaseActivity extends AppCompatActivity { private static int foregroundCount = 0; // 注意是個靜態(tài)變量 @Override protected void onStart() { super.onStart(); if (foregroundCount <= 0) { // TODO 這里處理從后臺恢復(fù)到前臺的邏輯 } foregroundCount++; } @Override protected void onStop() { foregroundCount--; if (foregroundCount <= 0) { // TODO 這里處理從前臺進(jìn)入到后臺的邏輯 } super.onStop(); } }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
源碼解析Android Jetpack組件之ViewModel的使用
Jetpack 是一個豐富的組件庫,它的組件庫按類別分為 4 類,分別是架構(gòu)(Architecture)、界面(UI)、 行為(behavior)和基礎(chǔ)(foundation)。本文將從源碼和大家講講Jetpack組件中ViewModel的使用2023-04-04Android中WebView與Js交互的實現(xiàn)方法
本文給大家介紹android中webview與js交互的實現(xiàn)方法,本文介紹的非常詳細(xì),具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)2016-05-05Android 中通過實現(xiàn)線程更新Progressdialog (對話進(jìn)度條)
這篇文章主要介紹了Android 中通過實現(xiàn)線程更新Progressdialog (對話進(jìn)度條)的相關(guān)資料,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2016-11-11Android程序開發(fā)通過HttpURLConnection上傳文件到服務(wù)器
這篇文章主要介紹了Android程序開發(fā)通過HttpURLConnection上傳文件到服務(wù)器的相關(guān)資料,需要的朋友可以參考下2016-01-01Android開發(fā)入門環(huán)境快速搭建實戰(zhàn)教程
最近想重新學(xué)習(xí)下Android,學(xué)習(xí)之前開發(fā)環(huán)境的搭建是個首先要解決的問題,所以下面這篇文章主要給大家介紹了Android開發(fā)環(huán)境搭建的相關(guān)資料,文中將實現(xiàn)的步驟一步步介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11