Acitivty 有七個生命週期:android
onCreate:當第一次調用一個Activity就會執行onCreate方法數據庫
onStart:當Activity處於可見狀態的時候就會調用onStart方法安全
onResume:當Activity能夠獲得用戶焦點的時候就會調用onResume方法,由被覆蓋狀態回到前臺或解鎖屏調用此方法。網絡
onRestart:當Activity沒有被銷燬的時候從新調用這個Activity就會調用onRestart方法多線程
onPause:當Activity被遮擋住的時候就會調用onPause方法,暫停當前activity。app
onStop:當Activity處於不可見狀態的時候就會調用onStop方法ide
onDestory:當Activity被銷燬時會調用onDestory方法佈局
環境:一共兩個頁面,A,B A頁面有一個button點擊以後打開B頁面
學習
activity啓動的時候:onCreate ---> onStart ---> onResume,打開A頁面:啓動時調用,可見狀態調用,獲取焦點調用。動畫
點擊button後打開B頁面此時A頁面的狀態是:onPause--->onStop,首先暫停A頁面activity,而後對B頁面的activity執行上面的三步,而後對A頁面進行中止操做。
當按返回鍵時:onRestart--->onStart--->onResume,首先暫停B頁面,其次對A頁面從新調用,可見狀態調用,獲取焦點是調用,最後在中止B頁面。
如下是運行時print截圖:
經過實施這些方法,您能夠監視Activity生命週期中的三個嵌套循環:
一、entire lifetime (整個生命週期)
一個Activity整個生命週期,存在於onCreate()方法和onDestroy()調用之間。你的Activity應該在onCreate()方法裏執行設置「全局」狀態(如定義佈局)。並在onDestroy()方法裏釋放全部剩餘資源。例如,若是你的活動有一個線程在後臺運行下載網絡數據,它能夠在onCreate()中建立該線程,而後在onDestroy()中中止線程。
二、visible lifetime(可見生命週期)
一個Activity可見生命週期,存在於onStart()和onStop()調用之間。在此期間,用戶能夠看到屏幕上的activity並與之交互。當一個其餘的Activity啓動,而且這個Activity徹底不可見的時候,onStop()方法就會被調用。在這兩個方法,你能夠保持該Activity須要展現給用戶的資源。例如,您能夠在onStart()方法裏註冊一個BroadcastReceiver來監控你的UI的變化,並在onStop()方法裏註銷它。在整個生命週期的活動中,系統可能會調用onStart()和onStop()屢次,由於活動之間交替進行隱藏或顯示給用戶。
三、 foreground lifetime(前臺生命週期)
一個Activity前臺生命週期,存在於onResume()和onPause()調用之間。在這段時間裏,這個Activity在其餘全部Activity的前面,擁有用戶輸入焦點。一個Activity能夠常常在前臺狀態發生轉換—好比,當設備休眠或者彈出了個對話框。由於常常會發生轉換,因此在這兩個方法之間的代碼應該是輕量級的,防止致使其餘轉換變慢使得用戶須要等待。
一個Activity本質上只有三種狀態:
Resumed(運行)、Paused(暫停)、Stopped(中止),由於從Activity被建立以後,它只可能在這三種狀態保持長久的停 留,其餘的回調方法結束後的狀態都只能稱之爲過渡狀態。好比進入到onStart方法後,執行完該方法,會當即進入到OnResume方法。(這裏所說的 狀態都是指對應的某個方法返回以後)。
Activity至關於一個servlet,咱們的Activity處在這個容器中,一切建立實例、初始化、銷燬實例等過程都是容器來調用的,這也就是所謂的「Don't call me, I'll call you.」機制。
咱們來看一下這一張經典的生命週期流程圖:
相信很多朋友也已經看過這個流程圖了,也基本瞭解了Activity生命週期的幾個過程,咱們就來講一說這幾個過程。
1.啓動Activity:系統會先調用onCreate方法,而後調用onStart方法,最後調用onResume,Activity進入運行狀態。
2.當前Activity被其餘Activity覆蓋其上或被鎖屏:系統會調用onPause方法,暫停當前Activity的執行。
3.當前Activity由被覆蓋狀態回到前臺或解鎖屏:系統會調用onResume方法,再次進入運行狀態。
4.當前Activity轉到新的Activity界面或按Home鍵回到主屏,自身退居後臺:系統會先調用onPause方法,而後調用onStop方法,進入停滯狀態。
5.用戶後退回到此Activity:系統會先調用onRestart方法,而後調用onStart方法,最後調用onResume方法,再次進入運行狀態。
6.當前Activity處於被覆蓋狀態或者後臺不可見狀態,即第2步和第4步,系統內存不足,殺死當前Activity,然後用戶退回當前Activity:再次調用onCreate方法、onStart方法、onResume方法,進入運行狀態。
7.用戶退出當前Activity:系統先調用onPause方法,而後調用onStop方法,最後調用onDestory方法,結束當前Activity。
生命週期對於用戶體驗的實際做用:
activity生命週期不一樣的週期能夠寫不一樣的代碼,舉個例子,好比你正在播放音樂的時候忽然電話來了,這個時候不可能一邊接電話一邊聽音樂吧?這時你就須要在相應的週期裏面對播放進行處理,好比你能夠在當前activity失去焦點的時候暫停播放。
我還找了一些資料用以擴充學習:原文連接
每個活動( Activity )都處於某一個狀態,對於開發者來講,是沒法控制其應用程序處於某一個狀態的,這些均由系統來完成。
可是當一個活動的狀態發生改變的時候,開發者能夠經過調用 onXX() 的方法獲取到相關的通知信息。
在實現 Activity 類的時候,經過覆蓋( override )這些方法便可在你須要處理的時候來調用。
•onCreate :當活動第一次啓動的時候,觸發該方法,能夠在此時完成活動的初始化工做。
onCreate 方法有一個參數,該參數能夠爲空( null ),也能夠是以前調用 onSaveInstanceState()方法保存的狀態信息。
•onStart :該方法的觸發表示所屬活動將被展示給用戶。
•onResume :當一個活動和用戶發生交互的時候,觸發該方法。
•onPause :當一個正在前臺運行的活動由於其餘的活動須要前臺運行而轉入後臺運行的時候,觸發該方法。這時候須要將活動的狀態持久化,好比正在編輯的數據庫記錄等。
•onStop :當一個活動再也不須要展現給用戶的時候,觸發該方法。若是內存緊張,系統會直接結束這個活動,而不會觸發 onStop 方法。 因此保存狀態信息是應該在onPause時作,而不是onStop時作。活動若是沒有在前臺運行,都將被中止或者Linux管理進程爲了給新的活動預留足 夠的存儲空間而隨時結束這些活動。所以對於開發者來講,在設計應用程序的時候,必須時刻牢記這一原則。在一些狀況下,onPause方法或許是活動觸發的 最後的方法,所以開發者須要在這個時候保存須要保存的信息。
•onRestart :當處於中止狀態的活動須要再次展示給用戶的時候,觸發該方法。
•onDestroy :當活動銷燬的時候,觸發該方法。和 onStop 方法同樣,若是內存緊張,系統會直接結束這個活動而不會觸發該方法。
•onSaveInstanceState :系統調用該方法,容許活動保存以前的狀態,好比說在一串字符串中的光標所處的位置等。
一般狀況下,開發者不須要重寫覆蓋該方法,在默認的實現中,已經提供了自動保存活動所涉及到的用戶界面組件的全部狀態信息。
4. 必調用的三個方法:onCreate() –> onStart() –> onResume(),用AAA表示
(1)父Activity(A)啓動,點擊啓動子Activity(B),子Actvity退出,返回父Activity調用順序以下:
AAA –> onFreeze() –> onPause() –> B onCreate() -> B onStart() -> B onResume –> onStop() –> onRestart() –> onStart()->onResume()
(2)用戶點擊Home,Actvity調用順序以下
AAA –> onFreeze() –> onPause() –> onStop() — Maybe –> onDestroy()
( 3 ) 用戶點擊back鍵,Activity調用順序以下:
AAA-> onPause() –> onStop() –> onDestroy() ->onCreate()->onStart()->onResume()
(4)調用finish(), Activity調用順序以下
AAA –> onPause() –> onStop() –> onDestroy()
(5)在Activity上顯示dialog, Activity調用順序以下
AAA -> onPause()
(6)在父Activity上顯示透明的或非全屏的activity,Activity調用順序以下
AAA –> onFreeze() –> onPause()
(7)設備進入睡眠狀態,Activity調用順序以下
AAA –> onFreeze() –> onPause()
5. 和其餘手機平臺的應用程序同樣,Android的應用程序的生命週期是被統一掌控的,也就是說咱們寫的應用程序命運掌握在別人(系統)的手裏,咱們不能改變它,只能學習並適應它。
簡單地說一下爲何是這樣:咱們手機在運行一個應用程序的時候,有可能打進來電話發進來短信,或者沒有電了,這時候程序都會被中斷,優先去服務電話的基本功能,另外系統也不容許你佔用太多資源,至少要保證電話功能吧,因此資源不足的時候也就有可能被幹掉。
言歸正傳,Activity的基本生命週期以下代碼所示:
Java 代碼
public class MyActivity extends Activity {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
你本身寫的Activity會按須要重載這些方法,onCreate是免不了的,在一個Activity正常啓動的過程當中,他們被調用的順序是 onCreate -> onStart -> onResume, 在Activity被幹掉的時候順序是onPause -> onStop -> onDestroy ,這樣就是一個完整的生命週期,可是有人問了 ,程序正運行着呢來電話了,這個程序咋辦?停止了唄,若是停止的時候新出的一個Activity是全屏的那麼:onPause->onStop,恢 復的時候onStart->onResume,若是打斷這個應用程序的是一個Theme爲Translucent 或者Dialog 的Activity那麼只是onPause ,恢復的時候onResume 。
詳細介紹一下這幾個方法中系統在作什麼以及咱們應該作什麼:
onCreate: 在這裏建立界面,作一些數據的初始化工做
onStart: 到這一步變成用戶可見不可交互的
onResume: 變成和用戶可交互的,(在activity棧系統經過棧的方式管理這些個Activity的最上面,運行完彈出棧,則回到上一個Activity)
onPause:到這一步是可見但不可交互的,系統會中止動畫等消耗CPU 的事情
從上文的描述已經知道,應該在這裏保存你的一些數據,由於這個時候你的程序的優先級下降,有可能被系統收回。在這裏保存的數據,應該在onResume裏讀出來,注意:這個方法裏作的事情時間要短,由於下一個activity不會等到這個方法完成才啓動
onstop:變得不可見,被下一個activity覆蓋了
onDestroy: 這是activity被幹掉前最後一個被調用方法了,多是外面類調用finish方法或者是系統爲了節省空間將它暫時性的幹掉,能夠用 isFinishing()來判斷它,若是你有一個Progress Dialog在線程中轉動,請在onDestroy裏把他cancel掉,否則等線程結束的時候,調用Dialog的cancel方法會拋異常的。 onPause,onstop, onDestroy,三種狀態下activity都有可能被系統幹掉,爲了保證程序的正確性,你要在onPause()裏寫上持久層操做的代碼,將用戶編 輯的內容都保存到存儲介質上(通常都是數據庫 )。實際工做中由於生命週期的變化而帶來的問題也不少,好比你的應用程序起了新的線程在跑,這時候中斷了,你還要去維護那個線程,是暫停仍是殺掉仍是數據 回滾,是吧?由於Activity可能被殺掉,因此線程中使用的變量和一些界面元素就千萬要注意了,通常我都是採用Android的消息機制 [Handler,Message]來處理多線程和界面交互的問題。這個我後面會講一些。
相關問題:
1. 能說下Android應用的入口點嗎?
真正的Android入口點是application的main,你能夠看下androidmanifest.xml的包含關係就清楚了。能夠沒有Activity可是必須有Application。
2. 若是後臺的Activity因爲某緣由被系統回收了,如何在被系統回收以前保存當前狀態?
在」暫停 onPause」 狀態將數據保存。
3. 如何退出Activity?如何安全退出已調用多個Activity的Application?
對於單一Activity的應用來講,退出很簡單,直接finish()便可。固然,也能夠用killProcess()和System.exit()這樣的方法。
4. 返回鍵與Home鍵區別?
back鍵默認行爲是finish處於前臺的Activity的,即Activity的狀態爲Destroy狀態爲止,再次啓動該Activity是從 onCreate開始的(不會調用onSaveInstanceState()方法)。Home鍵默認是stop前臺的Activity即狀態爲 onStop爲止,而不是Destroy,若再次啓動它,會調用onSaveInstanceState() 方法,保持上次Activity的狀態則是從OnRestart開始的---->onStart()--->onResume()。
5. 若是後臺的Activity因爲某緣由被系統回收了,如何在被系統回收以前保存當前狀態?onSaveInstanceState()
當你的程序中某一個Activity A在運行時,主動或被動地運行另外一個新的Activity B,這個時候A會執行onSaveInstanceState()。B完成之後又會來找A,這個時候就有兩種狀況:一是A被回收,二是A沒有被回收,被回 收的A就要從新調用onCreate()方法,不一樣於直接啓動的是這回onCreate()裏是帶上了參數savedInstanceState;而沒被 收回的就直接執行onRestart()->onStart()->onResume(),跳過onCreate()了。
6. 你後臺的Activity被系統回收怎麼辦:onSaveInstanceState
當你的程序中某一個Activity A 在運行時中,主動或被動地運行另外一個新的Activity B,這個時候A會執行
Java代碼
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
B 完成之後又會來找A, 這個時候就有兩種狀況,一種是A被回收,一種是沒有被回收,被回收的A就要從新調用onCreate()方法,不一樣於直接啓動的是這回 onCreate()裏是帶上參數savedInstanceState,沒被收回的就仍是onResume就行了。
savedInstanceState是一個Bundle對象,你基本上能夠把他理解爲系統幫你維護的一個Map對象。在onCreate()裏你可能會用到它,若是正常啓動onCreate就不會有它,因此用的時候要判斷一下是否爲空。
Java代碼
if(savedInstanceState != null){
long id = savedInstanceState.getLong("id");
}
就像官方的Notepad教程裏的狀況,你正在編輯某一個note,忽然被中斷,那麼就把這個note的id記住,再起來的時候就能夠根據這個id去把那 個note取出來,程序就完整一些。這也是看你的應用需不須要保存什麼,好比你的界面就是讀取一個列表,那就不須要特殊記住什麼,哦, 沒準你須要記住滾動條的位置(滾動條的位置如何記住?)...
7. 怎樣關閉一個Activity;怎樣關閉一個Application?
ActivityManager activityMgr= (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
activityMgr.restartPackage(getPackageName());
最後還須要添加這個權限才行:
<!-- 關閉應用程序的權限 -->
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
8. 橫豎屏切換的生命週期
9. Activity棧
上面提到開發者是沒法控制Activity的狀態的,那Activity的狀態又是按照何種邏輯來運做的呢?這就要知道 Activity 棧。
每一個Activity的狀態是由它在Activity棧(是一個後進先出LIFO,包含全部正在運行Activity的隊列)中的位置決定的。
當一個新的Activity啓動時,當前的活動的Activity將會移到Activity棧的頂部。
若是用戶使用後退按鈕返回的話,或者前臺的Activity結束,在棧上的Activity將會移上來並變爲活動狀態。以下圖所示:
一個應用程序的優先級是受最高優先級的Activity影響的。當決定某個應用程序是否要終結去釋放資源,Android內存管理使用棧來決定基於Activity的應用程序的優先級。Activity狀態 通常認爲Activity有如下四種狀態: 活動的:當一個Activity在棧頂,它是可視的、有焦點、可接受用戶輸入的。Android試圖盡最大可能保持它活動狀態,殺死其它Activity來確保當前活動Activity有足夠的資源可以使用。當另一個Activity被激活,這個將會被暫停。 暫停: 在不少狀況下,你的Activity可視可是它沒有焦點,換句話說它被暫停了。有可能緣由是一個透明或者非全屏的Activity被激活。 當被暫停,一個Activity仍會當成活動狀態,只不過是不能夠接受用戶輸入。在極特殊的狀況下,Android將會殺死一個暫停的Activity來爲活動的Activity提供充足的資源。當一個Activity變爲徹底隱藏,它將會變成中止。 中止:當一個Activity不是可視的,它「中止」了。這個Activity將仍然在內存中保存它全部的狀態和會員信息。儘管如此,當其它地方須要內存 時,它將是最有可能被釋放資源的。當一個Activity中止後,一個很重要的步驟是要保存數據和當前UI狀態。一旦一個Activity退出或關閉了, 它將變爲待用狀態。 待用: 在一個Activity被殺死後和被裝在前,它是待用狀態的。待用Acitivity被移除Activity棧,而且須要在顯示和可用以前從新啓動它。