# [Activity](https://developer.android.com/guide/components/activities?hl=zh-tw) 生命週期

#### 非了解每個生命週期做了什麼 而是了解什麼事情該在哪個生命週期做
* [onCreated()](https://developer.android.com/reference/android/app/Activity?hl=zh-tw#onCreate(android.os.Bundle)):Activity 第一次被啟動時執行,主要為做一些靜態設定
```
onNewIntent
透過 Intent 回到某 Activity 觸發
如:intent 至 singleTask 的 Activity
intent 至正在頂層的 singleTop Activity
從通知 intent 至 App
```
* onRestart():當前activity重新被啟動時呼叫的;繫結一些監聽器等
* onStart():activity要被顯示出來的時候執行
```
onRestoreInstanceState
非使用者主動移除並重建 App 時觸發
例如:旋轉畫面
可用 onSaveInstanceState 儲存的 Bundle 復原資料
```
```
onPostCreate
Activity 徹底運轉起來時執行
在使用ActionBarDrawerToggle時,當螢幕選轉時同步更新 Toggle State
例如官方提供的例子:
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
也可用來在布局完成時就取得某 view 的寬高
```
* onResume():activity 要移至前景讓使用者能進行互動時執行
```
onPostResume
onResume執行完後調用
```
```
onWindowFocusChanged
```
* onPause():Activity 可見但失去焦點時觸發,一般在該函式中執行儲存當前的資料
* 不能執行太耗時的工作,因為覆蓋該 Activity 的新 Activity 會在原 Activity 執行完 onPause 方法後才會被開啟
```
onSaveInstanceState
在 Activity 可能被移除的情況下,在 onPause 方法之後執行
(按 Home、多工、旋轉螢幕、intent 至新 activity)
```
* onStop():activity被移至完全不可見時觸發
* 通常不在 onStop 儲存資料,因為某些時候 Stop 不一定會被觸發,如:旋轉螢幕
* onDestroy():退出當前activity時呼叫的,當然如果程式中呼叫finish()或者說android系統當前資源不夠用時就會被呼叫。
### 筆記
* ~~onCreate 階段畫面還不可見,此時對 UI 的更改並不會更改 View,不會調用 invalidate 方法
因此即使用非 main Thread操作變更 UI 的動作也不會有錯誤(但畫面也不會有變化)~~
```
Textview.setText->TextView.checkForRelayout->invalidate->ViewGroup.invalidateChild-> ViewRootImpl.checkThread()方法 crush
```
~~onCreate 階段結束後,畫面進入可見狀態,任何更新view的操作都會調用 invalidate 方法~~
[參考](https://www.jianshu.com/p/c39203884209)
* Android 啟動 Activity 時必須知道裝置組態,因為裝置組態會影響應用程式使用的資源
因此當裝置組態改變時(螢幕方向、螢幕尺寸、使用者設定的選項例如語言)Android 會更新所有顯示使用者介面的東西,Activity 就會被銷毀並重建
* onDestroy 階段不一定會被執行,當 Anroid 因內存不夠而銷毀 App 時,將不會執行 onDestroy
* 相同情境下 onDestroy 也有可能觸發或不被觸發
home > 多工 > 滑掉
這也代表釋放資源或是儲存資料等動作最好放在 onStop 或 onPause 等一定會被執行到的階段
* onSaveInstanceState 在 onPause 後、onStop前觸發(返回鍵關閉 Activity 不會觸發)
儲存的 Bundle 可以在 onCreate 或 onRestoreInstanceState 被恢復
* onCreate、onStart、onPostCreate、onResume、onPostResume 會接續加入排程佇列
(在該生命週期中使用 Handler().post()方法,post 的執行內容會在後面才被執行)
```
2019-01-10 13:15:25.392 I/System.out: onCreate
2019-01-10 13:15:25.396 I/System.out: onStart
2019-01-10 13:15:25.397 I/System.out: onPostCreate
2019-01-10 13:15:25.400 I/System.out: onResume
2019-01-10 13:15:25.402 I/System.out: onPostResume
2019-01-10 13:15:25.420 I/System.out: onCreate post
2019-01-10 13:15:25.420 I/System.out: onStart post
2019-01-10 13:15:25.421 I/System.out: onPostCreate post
2019-01-10 13:15:25.421 I/System.out: onResume post
2019-01-10 13:15:25.421 I/System.out: onPostResume post
```
onRestart、onStart、onResume 會接續加入排程佇列
```
2019-01-08 13:35:48.992 I/System.out: onRestart
2019-01-08 13:35:48.998 I/System.out: onStart
2019-01-08 13:35:48.999 I/System.out: onResume
2019-01-08 13:35:49.039 I/System.out: onRestart post
2019-01-08 13:35:49.039 I/System.out: onStart post
2019-01-08 13:35:49.039 I/System.out: onResume post
```
* onPause > Activity 可見但失去焦點時觸發
如:有另一個不是全尺寸的或是透明的 Activity 蓋在上面
雙視窗切換時為 onPause <-> onResume
* onResume > Activity 要移至前景時執行,執行後 Activity 會被聚焦
因此若 Activity 在暫停狀態(可見但不在前景、沒有焦點)被 recreate(如:旋轉),新 Activity 只會執行到 onStart,直到要移回前景時才會執行 onResume
* 若暫停狀態下被 Recreate 執行到 onStart 階段後,將Activity 直接變成不可見狀態並移除,則會直接從 onStart 跳至 onStop
* 關畫面狀態下 build App ,會執行 resume > pause > stop階段