[TOC]
## 生命周期

當我們從activity A到Activity B時,執行的生命周期的執行順序如下:?
A.onPause -> B.onCreate -> B.onStart -> B.onResume -> A.onStop
當我們從activity B返回Activity A時,執行的生命周期的執行順序如下:?
B.onPause -> A.onRestart ->A.onStart -> A.onResume -> B.onStop -> B.onDestory
程序按back 退出: onPause()->onStop()->onDestory(),再進入:onCreate()->onStart()->onResume();
程序按home 退出: onPause()->onStop(),再進入:onRestart()->onStart()->onResume();
## onSaveInstanceState or onRestoreInstanceState
onSaveInstanceState在 onstop之前 不保證與onPause的順序
onSaveInstanceState的調用遵循一個重要原則,即當系統“未經你許可”時銷毀了你的activity,則 onSaveInstanceState會被系統調用,這是系統的責任,因為它必須要提供一個機會讓你保存你的數據(當然你不保存那就隨便你了)。
1. 配置發生變化(鍵盤 旋轉 ..)
2. 內存不足被回收
## 前后切換監聽
當我們從activity A到Activity B時,執行的生命周期的執行順序如下:?
A.onPause -> B.onCreate -> B.onStart -> B.onResume -> A.onStop
因此我們在Activity的onStart和onStop方法中用變量count計數,在onStart中先判斷是否等于0再將變量加1,onStop中先減1再判斷是否等于0
~~~
假設應用有兩個Activity,分別為A和B。
情況1,首先啟動A,A再啟動B,然后關掉B:
A啟動后(onStart后),count=1;
A啟動B,先B.onStart 然后A.onStop,count先加1后減1,count為1。
關掉B,先A.onStart 然后B.onStop,count先加1后減1,count為1
情況2,首先啟動A,然后按Home鍵返回桌面:
A啟動后(onStart后),count=1;
按Home鍵返回桌面,會執行A.onStop,count的計數變位0。
~~~
關鍵代碼
~~~
public class BaseTaskSwitch implements Application.ActivityLifecycleCallbacks {
public int mCount = 0;
private OnTaskSwitchListener mOnTaskSwitchListener;
private static BaseTaskSwitch mBaseLifecycle;
public static BaseTaskSwitch init(Application application) {
if (null == mBaseLifecycle) {
mBaseLifecycle = new BaseTaskSwitch();
application.registerActivityLifecycleCallbacks(mBaseLifecycle);
}
return mBaseLifecycle;
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityStarted(Activity activity) {
if (mCount++ == 0) {
mOnTaskSwitchListener.onTaskSwitchToForeground();
}
}
@Override
public void onActivityResumed(Activity activity) {}
@Override
public void onActivityPaused(Activity activity) {}
@Override
public void onActivityStopped(Activity activity) {
if (--mCount == 0) {
mOnTaskSwitchListener.onTaskSwitchToBackground();
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public void onActivityDestroyed(Activity activity) {}
public void setOnTaskSwitchListener(OnTaskSwitchListener listener) {
mOnTaskSwitchListener = listener;
}
public interface OnTaskSwitchListener {
void onTaskSwitchToForeground();
void onTaskSwitchToBackgroun
~~~
## 啟動模式
### 1\. Standard 標準模式
**說明:**?Android創建Activity時的默認模式,假設沒有為Activity設置啟動模式的話,默覺得標準模式。每次啟動一個Activity都會又一次創建一個新的實例入棧,無論這個實例是否存在。
**生命周期:** 如上所看到的,每次被創建的實例Activity 的生命周期符合典型情況,它的onCreate、onStart、onResume都會被調用。
**舉例:** 此時Activity 棧中以此有A、B、C三個Activity,此時C處于棧頂,啟動模式為**Standard 模式**。
若在C Activity中加入點擊事件,須要跳轉到還有一個同類型的C Activity。結果是還有一個C Activity進入棧中,成為棧頂。?
### 2\. SingleTop 棧頂復用模式
**說明:** 分兩種處理情況:須要創建的Activity已經處于棧頂時,此時會直接復用棧頂的Activity。不會再創建新的Activity;若須要創建的Activity不處于棧頂,此時會又一次創建一個新的Activity入棧,同Standard模式一樣。
**生命周期:** 若情況一中棧頂的Activity被直接復用時,它的onCreate、onStart不會被系統調用,由于它并沒有發生改變。可是一個新的方法?**onNewIntent**會被回調(Activity被正常創建時不會回調此方法)。
#### 3\. SingleTask 棧內復用模式
**說明:** 若須要創建的Activity已經處于棧中時,此時不會創建新的Activity,而是將存在棧中的Activity上面的其他Activity所有銷毀,使它成為棧頂。
**生命周期:** 同SingleTop 模式中的情況一同樣。僅僅會又一次回調Activity中的?**onNewIntent**方法
**舉例:** 此時Activity 棧中以此有A、B、C三個Activity。此時C處于棧頂,啟動模式為**SingleTask 模式**。
情況一:在C Activity中加入點擊事件,須要跳轉到還有一個同類型的C Activity。結果是直接用棧頂的C Activity。情況二:在C Activity中加入點擊事件,須要跳轉到還有一個A Activity。
結果是將A Activity上面的B、C所有銷毀,使A Activity成為棧頂。
### 4\. SingleInstance 單實例模式
**說明:**?SingleInstance比較特殊,是全局單例模式,是一種加強的SingleTask模式。它除了具有它所有特性外,還加強了一點:具有此模式的Activity僅僅能單獨位于一個任務棧中。
這個經常使用于系統中的應用,比如Launch、鎖屏鍵的應用等等,整個系統中僅僅有一個!所以在我們的應用中一般不會用到。了解就可以。
**舉例:** 比方 A Activity是該模式,啟動A后。系統會為它創建一個單獨的任務棧,由于棧內復用的特性。興許的請求均不會創建新的Activity,除非這個獨特的任務棧被系統銷毀。
## 參考資料
[Android前后臺切換監聽的再進化](https://blog.csdn.net/fei20121106/article/details/79568838)
- Android
- 四大組件
- Activity
- Fragment
- Service
- 序列化
- Handler
- Hander介紹
- MessageQueue詳細
- 啟動流程
- 系統啟動流程
- 應用啟動流程
- Activity啟動流程
- View
- view繪制
- view事件傳遞
- choreographer
- LayoutInflater
- UI渲染概念
- Binder
- Binder原理
- Binder最大數據
- Binder小結
- Android組件
- ListView原理
- RecyclerView原理
- SharePreferences
- AsyncTask
- Sqlite
- SQLCipher加密
- 遷移與修復
- Sqlite內核
- Sqlite優化v2
- sqlite索引
- sqlite之wal
- sqlite之鎖機制
- 網絡
- 基礎
- TCP
- HTTP
- HTTP1.1
- HTTP2.0
- HTTPS
- HTTP3.0
- HTTP進化圖
- HTTP小結
- 實踐
- 網絡優化
- Json
- ProtoBuffer
- 斷點續傳
- 性能
- 卡頓
- 卡頓監控
- ANR
- ANR監控
- 內存
- 內存問題與優化
- 圖片內存優化
- 線下內存監控
- 線上內存監控
- 啟動優化
- 死鎖監控
- 崩潰監控
- 包體積優化
- UI渲染優化
- UI常規優化
- I/O監控
- 電量監控
- 第三方框架
- 網絡框架
- Volley
- Okhttp
- 網絡框架n問
- OkHttp原理N問
- 設計模式
- EventBus
- Rxjava
- 圖片
- ImageWoker
- Gilde的優化
- APT
- 依賴注入
- APT
- ARouter
- ButterKnife
- MMKV
- Jetpack
- 協程
- MVI
- Startup
- DataBinder
- 黑科技
- hook
- 運行期Java-hook技術
- 編譯期hook
- ASM
- Transform增量編譯
- 運行期Native-hook技術
- 熱修復
- 插件化
- AAB
- Shadow
- 虛擬機
- 其他
- UI自動化
- JavaParser
- Android Line
- 編譯
- 疑難雜癥
- Android11滑動異常
- 方案
- 工業化
- 模塊化
- 隱私合規
- 動態化
- 項目管理
- 業務啟動優化
- 業務架構設計
- 性能優化case
- 性能優化-排查思路
- 性能優化-現有方案
- 登錄
- 搜索
- C++
- NDK入門
- 跨平臺
- H5
- Flutter
- Flutter 性能優化
- 數據跨平臺