Activity是啥?
簡單來說就是用來和使用者互動的介面,由各個控制元件組成 ,將內容介面化展現於使用者面前,接收使用者的觸控事件和使用者進行互動,可以說是使用最頻繁的元件了。
Activity生命週期
生命週期: onCreate -> onStart -> onResume ->onPause -> onStop-> onDestroy 以及 onRestart 方法
一個Activity從建立到銷燬的生命週期流程如下:
開啟一個介面
2019-01-26 15:36:04.134 30064-30064/com.sjc.myapplication I/生命週期-----MainActivity: onCreate:
2019-01-26 15:36:04.207 30064-30064/com.sjc.myapplication I/生命週期-----MainActivity: onStart:
2019-01-26 15:36:04.221 30064-30064/com.sjc.myapplication I/生命週期-----MainActivity: onResume:
複製程式碼
按下返回鍵
2019-01-26 15:36:12.381 30064-30064/com.sjc.myapplication I/生命週期-----MainActivity: onPause:
2019-01-26 15:36:12.943 30064-30064/com.sjc.myapplication I/生命週期-----MainActivity: onStop:
2019-01-26 15:36:12.944 30064-30064/com.sjc.myapplication I/生命週期-----MainActivity: onDestroy:
複製程式碼
- onCreate 介面被建立,我們一般在這裡進行一些檢視和資料以及響應事件的初始化工作。(initView(),initData(),initAction())
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
initView();
initData();
initAction();
}
private void initView(){};
private void initData(){};
private void initAction(){};
複製程式碼
- onStart 介面可見,此時介面還不可互動。
- onResume 介面可以進行互動,比如觸發一些點選事件。
- onPause 介面失去互動,此時不可以進行互動。常見的導致該生命週期的執行的行為可能是:使用者按下Home鍵、按下back鍵、跳轉到下一個頁面、彈出一個Dialog,或者PopupWindow等。此時我們可以做一些儲存資料和停止動畫等,但是不能太耗時,否則會影響下個頁面的跳轉(頁面與頁面之前跳轉,先執行當前頁面的onPause方法,然後執行下一個頁面的 生命週期,具體執行下面有說明)。
- onStop 介面完全不可見的時候呼叫。兩個Activity跳轉,前一個Activity的onStop執行是在第二個Activity完全可見並可以進行互動後執行的(onCreate,onStart,onResume)
- onDestroy 介面被銷燬,一般我們在這裡做一些資源釋放的操作,比如登出廣播,關閉彈窗(如果頁面被銷燬,彈窗未被關閉,則會造成窗體洩漏),關閉動畫等。
- onRestart 介面重新可見,從一個頁面返回上一個頁面,首先會呼叫上一個頁面的 onRestart 方法,其次呼叫上一個頁面的 onStart、onResume方法
兩個頁面進行跳轉,ActivityA --> ActivityB 再從ActivityB按下返回鍵返回到ActivityA,其呼叫的生命週期方法為:
- 首先啟動 ActivityA:
2019-02-18 23:08:28.362 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onCreate:
2019-02-18 23:08:28.388 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onStart:
2019-02-18 23:08:28.390 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onResume:
複製程式碼
- 在 ActivityA 中啟動 ActivityB
2019-02-18 23:08:33.347 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onPause:
2019-02-18 23:08:33.371 4980-4980/com.sjc.myapplication I/生命週期-----ActivityB: onCreate:
2019-02-18 23:08:33.393 4980-4980/com.sjc.myapplication I/生命週期-----ActivityB: onStart:
2019-02-18 23:08:33.395 4980-4980/com.sjc.myapplication I/生命週期-----ActivityB: onResume:
2019-02-18 23:08:33.819 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onStop:
複製程式碼
- 在 ActivityB 中按下返回鍵
2019-02-18 23:10:59.457 4980-4980/com.sjc.myapplication I/生命週期-----ActivityB: onPause:
2019-02-18 23:10:59.482 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onRestart:
2019-02-18 23:10:59.482 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onStart:
2019-02-18 23:10:59.483 4980-4980/com.sjc.myapplication I/生命週期-----ActivityA: onResume:
2019-02-18 23:10:59.813 4980-4980/com.sjc.myapplication I/生命週期-----ActivityB: onStop:
2019-02-18 23:10:59.814 4980-4980/com.sjc.myapplication I/生命週期-----ActivityB: onDestroy:
複製程式碼
Activity銷燬時儲存資料
Activity 異常銷燬的時候,會呼叫 ==onSaveInstanceState== 方法儲存資料,該方法是在 onStop 之前執行,我們可以使用 Bundle 來儲存資料,當 Activity 重建的時候會呼叫 ==onRestoreInstanceState== 方法,我們可以通過 onRestoreInstanceState(Bundle savedInstanceState)傳遞過來的Bundle來獲取之前儲存的資料。進行資料恢復。當然也可以在onCreate(Bundle savedInstanceState)方法裡面取出來。
另:onSaveInstanceState 和 onRestoreInstanceState 方法中,系統自動為我們做了一些操作: 例如:Edittext 自動還原填寫內容, ListView 還原滾動位置,因為每一個View都有自己的 onSaveInstanceState 和 onRestoreInstanceState 方法。
activity異常銷燬的場景:
- 1.螢幕旋轉會導致Activity重建(可以通過設定 android : configChanges = "orientation" 來防止Activity重建,還可以通過設定 android:screenOrientation="portrait" 鎖定Activity方向)
- 2.記憶體吃緊,導致優先順序低的Activity被回收掉。
Activity 的四種狀態:
- running:處於前臺,和使用者進行直接的互動。(系統最不願意回收)
- Paused: 仍然可見,但是不可以互動。(系統不願意回收)
- Stoped: 不可見,處於後臺。(記憶體吃緊的時候,有可能會被回收)
- Killed: 被殺死,已經從Activity棧中移除。(系統傾向於回收這種 Activity)
Activity四種啟動模式:
通過在 mainfest 裡面的 android:launchMode= ""屬性來設定
複製程式碼
- standard 標準模式,如果不設定啟動模式,Android 系統會預設將啟動模式設定為該屬性。每啟動一次 Activity 就會==建立一個例項==壓入棧中(連續啟動兩個一樣的 Activity ,會建立兩個例項,按照先後順序壓入棧中)。
- singleTop 在建立例項的時候,首先會查詢任務棧==棧頂==是否有該 Activity 的例項存在,如果有就不再建立新的例項,直接使用棧中的例項。此時不會走 Activity 的 onCreate、onStart 生命週期方法,直接走 onPause--> onNewIntent --> onResume 方法。
- singleTask 在建立例項的時候,首先查詢任務棧==棧中==是否有該例項的存在,如果有就不重新建立,直接將該例項的上面的所有例項(Activity)移除(Finish),也是不會走 Activity 的 onCreate、onStart 生命週期方法,直接走 onPause--> onNewIntent --> onResume 方法。
- singleInstance 直接為該Activity在整個Android系統中建立一個==單獨的任務棧==(如果已經建立過,就不再重新建立),第一次建立時會走正常的生命週期流程,第二次直接走 onPause--> onNewIntent --> onResume 方法。
關於 taskAffinity 屬性(可以指定Activity所在的任務棧),在 launchMode 為 standard 和 singleTop 的時候是沒有作用的。具體作用體現在 singleTask 屬性上。 具體詳情連結 徹底弄懂Activity四大啟動模式
Activity任務棧:
- 棧是一個常用的資料結構,棧的特點是先進後出,佇列是先進先出
- Activity 是採用棧的資料結構進行管理的,最先開啟的 Activity 最後退出。
- 開啟一個應用的時候系統會預設分配一個任務棧,當所有 Activity 都退出時,棧就清空了。
- 在 Android 作業系統中是有多個任務棧的,一般一個應用對應一個任務棧。
- 預設情況下,關閉一個應用,就清空這個這個應用的任務棧,但是這個應用的程式還在。