為什么80%的碼農都做不了架構師?>>> ??
Acitivty 有七個生命周期:
onCreate:當第一次調用一個Activity就會執行onCreate方法
onStart:當Activity處于可見狀態的時候就會調用onStart方法
onResume:當Activity可以得到用戶焦點的時候就會調用onResume方法,由被覆蓋狀態回到前臺或解鎖屏調用此方法。
onRestart:當Activity沒有被銷毀的時候重新調用這個Activity就會調用onRestart方法
onPause:當Activity被遮擋住的時候就會調用onPause方法,暫停當前activity。
onStop:當Activity處于不可見狀態的時候就會調用onStop方法
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生命周期中的三個嵌套循環:
1、entire?lifetime?(整個生命周期)
一個Activity整個生命周期,存在于onCreate()方法和onDestroy()調用之間。你的Activity應該在onCreate()方法里執行設置“全局”狀態(如定義布局)。并在onDestroy()方法里釋放所有剩余資源。例如,如果你的活動有一個線程在后臺運行下載網絡數據,它可以在onCreate()中創建該線程,然后在onDestroy()中停止線程。
2、visible?lifetime(可見生命周期)
一個Activity可見生命周期,存在于onStart()和onStop()調用之間。在此期間,用戶可以看到屏幕上的activity并與之交互。當一個其他的Activity啟動,并且這個Activity完全不可見的時候,onStop()方法就會被調用。在這兩個方法,你可以保持該Activity需要展示給用戶的資源。例如,您可以在onStart()方法里注冊一個BroadcastReceiver來監控你的UI的變化,并在onStop()方法里注銷它。在整個生命周期的活動中,系統可能會調用onStart()和onStop()多次,因為活動之間交替進行隱藏或顯示給用戶。
3、?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棧,并且需要在顯示和可用之前重新啟動它。