最近學習android中關于Activity的生命周期方面,對于有些方面有所理解,希望寫下來記錄,方便以后查看,順便也克服一下自己的不會解釋的缺點。
關于Activity的生命周期的理解,將分為以下幾步:
棧的工作原理
Activity的運行狀態
Activity的生命周期詳細流程以及七大方法
Activity生命周期的示范實例
第一.棧的工作原理
首先,從開發者的角度看,一個應用是由多個Activity--也就是活動組成的,在官方解釋下,任務(Task)就是許多存放在棧中的Activity的集合,大概理解就是 每當用戶打開一個應用的時候,就像是創建了一個任務。而任務需要容器裝著,這個容器就叫做棧,也被稱為返回棧。返回棧遵循著先進后出的原則,意思是比如我們打開一個應用,第一個界面就是這個應用的主活動,這個主活動將進棧并處在這個棧的棧頂,表示這個活動是可見的并且能夠與用戶進行交互;然后我們點擊某個按鈕,切換到另外一個活動時,這個活動將會取代第一個活動并處在棧頂的位置,最后當我們點擊返回鍵時,這時第二個活動將會出棧并銷毀,第一個活動將會重新回到棧頂。
這個理解跟進棧,出棧方面有很大關系,不理解的請自行查閱啦。
第二.Activity的運行狀態
接著另外一個關于Activity的知識,需要講講,那就是Activity的狀態。
Activity的狀態有四種:
第一種:運行狀態,在Activity的運行狀態下,這個活動是可見的并且可以與用戶進行交互的,怎么理解呢,就是應用打開后我們所面對的第一個界面,這個界面就是指運行狀態下的Activity,那么這個活動我們是看得見的(可見的)并且我們可以進行操作(與用戶進行操作)。
第二種:暫停狀態,暫停狀態下的活動依舊是可見的但是,并不能與用戶進行交互。咦,這種狀態下的活動存在嗎?好像沒有遇到過 -- 有的,在應用下,當我們切換到第二個活動下有時會遇到一些對話框式的活動,除了這個對話框之外,陰影部分是不是第一個活動?那么這個第一個活動我們是可見的,但是我們并不能對其進行任何的操作,這種活動就是在暫停狀態下的。
第三種:停止狀態,停止狀態下的Activity,就是不可見并且無法進行交互的。在從第一個活動中切換到第二個活動時,第一個活動我們看不見并且也無法進行任何的操作,這種狀態就是停止狀態。
無論如何,這三種狀態,無論是暫停狀態,還是停止狀態,都是在棧中的,沒有出過棧。
第四種:銷毀狀態,這種狀態下的Activity將會被出棧,銷毀,將不存在在任務流程下,就是當我們處在第二個活動下,想要返回第一個活動時,我們就點擊返回鍵(Back),這時,第二個活動將會從棧中退出并銷毀,這種狀態就是銷毀狀態。
第三.Activity的生命周期詳細流程以及七大方法
在理解了Activity工作原理,Activity的狀態以后,就是Activity的生命周期部分
你有沒有注意到一個細節,就是關于關于Activity的工作原理,Activity的狀態,主要注重在兩點:可見性與可交互性,在Activity的生命周期中,也是圍繞這兩點。
先貼張圖:
這張圖就是Activity的生命周期,所涉及到的有七個Android關于Activity的方法。
網上有很多前輩大神的解釋都是一個個方法解釋的,我就換另外一種方式吧,我從用戶的角度將整個應用的開始到結束解釋一遍吧。
首先為了全面覆蓋所有要用到的方法,我從兩個應用來講。
1.第一種應用(切換界面)
(1)當我們點擊從手機的應用時,將會調用onCreate()→onStart()→onResume()這三個方法,那么這三個怎么去理解呢?
當我們點擊應用時,調用onCreate()時,表示正在第一次創建這個活動;調用onStart()方法時,表示現在這個活動為可見的;調用onResume()方法時,表示該活動準備好與用戶進行交互,也就是用戶可進行操作。這時,這個應用正處于運行狀態。
也就是說,
創建活動→可見性→可交互性→啟動主活動
就是,可見+可交互=運行狀態。
(2)那么我們準備點擊該界面上的一個按鈕進行切換到另外一個活動,這時,將會調用onPause()→onStop()方法。當調用onPause()方法時,表示該活動準備調用或啟動另外一個活動,也意味著該活動不可交互;當調用onStop()方法時,表示該活動已經變為不可見了。
我們只是探究主活動的方法調用,所以第二個活動的啟動不會說,但是是與啟動活動是相同的。
由此可見,主活動不交互性→主活動不可見性→啟動第二個活動
就是,不可見+不可交互=停止狀態。
(3)那當我們想要返回到主活動時,點擊返回鍵,將會調用主活動的onRestart()→onStart()→onResume()方法,那么這里其實跟剛開始啟動主活動是一樣的,但是這其中不一樣的就是一開始的方法調用,onCreate()是指方法第一次被創建才會執行,onRestart()是指重新調用已經被創造的活動,那么意思就是說該活動還是處于返回棧中,如果該活動還在棧中,就調用onRestart()。
那么這里一樣,重新調用→可見性→可交互性→返回主活動
那么,思考下,有沒有可能本來就創建過該活動,但是當我們切換到另外一個活動的時候,它卻偷偷跑了呢?
有的,當我們手機系統發現內存不夠的話,系統將會回收那些處于停止狀態下的活動,那么這個時候就會出現這種情況,創造該活動之后卻被系統清除了。
那么出現這種情況的話,當我們處于第二個活動而主活動卻被系統清除了,這時將會重新啟動該活動,也就是調用方法onCreate()→onStart()→onResume()方法。
(4)現在我們處于主活動,當我們想要回到手機的首頁,我們就要再次點擊返回鍵,這時將調用onPasue()→onStop()→onDestroy()方法,調用onDestroy()也就意味著該活動將退出棧頂并且被銷毀。
也就是說,不可交互性+不可見性+摧毀=銷毀狀態
所以切換到第二個活動會在 **運行狀態 到 停止狀態 **直接轉換。
在銷毀活動的時候,該活動就是處在銷毀狀態。
2.第二種應用(切換到對話框式的活動)
關于該應用的啟動與銷毀 我就不講了,都是一樣的原理。切換到對話框式的活動主要不一樣在切換部分。
(1)當我們準備點擊按鈕而彈出一個對話框式的活動,這只會調用onPause()方法,這個跟之前切換第二個活動有什么區別呢?我們之前切換第二個活動時所調用的是onPause()→onStop()方法。咦,那為什么不用調用onStop()方法呢?onPause()方法指的是該活動將不能與用戶進行交互,而Stop()方法指該活動不可見。
想想,當應用彈出對話框式的活動時,所看見的除對話框式活動之外,就是陰影部分下的主活動,這個主活動對于用戶來說是可見的但是無法對其進行操作,所以,該主活動是處在暫停狀態下的,只會調用onPause().
(2)那么當我們想從對話框式的活動回到主活動,我們將點擊返回鍵,這是將會調用onResume()方法,表示該活動準備好與用戶進行交互。
所以切換對話框式的活動會在 運行狀態 到 暫停狀態之間轉換。
可以發現,整個Activity的生命周期都是圍繞 Activity的先進后出的返回棧的工作原理,Activity的四大狀態跟活動的可見性與可交互性。
我先列出七大Activity的方法:
onCreate():在活動的第一次被創建的時候被調用
onStart():表示該活動為可見
onResume():表示該活動已經準備好與用戶進行交互
onPause():表示該活動正在調用或啟動另外一個應用,意味該活動不可與用戶進行交互
onStop():表示該活動從可見轉為不可見
onDestroy():表示該活動將被銷毀
onRestart():表示該活動將被重新調用或啟動
第四.Activity生命周期的示范實例
關于代碼的實例的話我是模仿郭霖老師寫的《第一行代碼》中的。
我構建了三個活動:第一個主活動為MainActivity.lava
public classMainActivityextendsAppCompatActivity {
public static finalStringTAG="MainActivity";
@Override
protected voidonCreate(Bundle savedInstanceState) {//重寫onCreate()方法,傳入之前推出所保存的Activity的數據狀態
super.onCreate(savedInstanceState);//調用父類方法onCreate(),傳入savedInstanceState
setContentView(R.layout.activity_main);//調用setContentView()方法構建視圖
}
Log.d(TAG,"onCreate");//通過Log打印應用信息,級別為debug
Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity);//獲取Button的實例,將View對象轉換為Button對象
Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity);//獲取Button的實例,將View對象轉換為Button對象
startNormalActivity.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
Intent intent =newIntent(MainActivity.this,NormalActivity.class);//構建一個Intent對象,第一個值為 上下文,第二個值為目標活動
startActivity(intent);//調用startActivity()方法,執行該Intent
}
});//為該控件注冊一個監聽器
startDialogActivity.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
Intent intent =newIntent(MainActivity.this,DialogActivity.class);//構建一個Intent對象,第一個值為context上下文,第二個值為目標活動
startActivity(intent);//將Intent傳入,執行該Intent
}
});//為該控件注冊一個監聽器
}
@Override
protected voidonStart() {//調用onStart()方法,表示該活動由不可見到可見
super.onStart();
Log.d(TAG,"onStart");//調用Log打印信息,級別為debug
}
@Override
protected voidonResume() {//調用onResume()方法,表示該活動準備好與用戶進行交互
super.onResume();
Log.d(TAG,"onResume");//調用Log打印信息,級別為debug
}
@Override
protected voidonPause() {//調用onPause()方法,表示該活動準備調用另外一個活動
super.onPause();
Log.d(TAG,"onPause");//調用Log打印信息,級別為debug
}
@Override
protected voidonStop() {//調用onStop()方法,表示該活動由可見轉為不可見
super.onStop();
Log.d(TAG,"onStop");//調用Log打印信息,級別為debug
}
@Override
protected voidonRestart() {//調用onRestart()方法,表示該活動由停止狀態轉向運行狀態
super.onRestart();
Log.d(TAG,"onRestart");//調用Log打印信息,級別為debug
}
@Override
protected voidonDestroy() {//調用onDestory()方法,表示該活動將被銷毀
super.onDestroy();
Log.d(TAG,"onDestory");//調用Log打印信息,級別為debug
}
@Override
protected voidonSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String data ="Something you just typed";//定義字符串data并賦值
outState.putString("data_key",data);//將值傳入,第一個為鍵,用于在目標活動找回數據,第二個值為需要保存的值
}
關于布局文件為activity_main.xml
<xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.activitylifecycletest.MainActivity">
<android:id="@+id/start_normal_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start NormalActivity"/>
<android:id="@+id/start_dialog_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start DialogActivity"
android:layout_below="@+id/start_normal_activity"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"/>
然后創建兩個活動名為NormalActivity(普通活動) 與 DialogActivity(對話框式的活動)
并以此自動構建兩個對應的布局文件
當我們點擊應用圖標時,我們將創建主活動,通過Log打印語句來了解整個activity的生命周期
這時在android Monitor下Log.d將打印出如下:
05-27 23:42:34.932 2254-2254/com.example.activitylifecycletest D/MainActivity: onCreate
05-27 23:42:34.934 2254-2254/com.example.activitylifecycletest D/MainActivity: onStart
05-27 23:42:34.936 2254-2254/com.example.activitylifecycletest D/MainActivity: onResume
以下為界面:
將會出現兩個按鈕,一個是用來切換NormalActivity的普通活動,另外一個是用來切換DialogActivity的對話框式的活動。
(1)點擊 start NormalActivity的按鈕,將會切換到NormalActivity的界面,這是Android Monitor將會打印出:
05-27 23:51:10.012 2254-2254/com.example.activitylifecycletest D/MainActivity: onPause
05-27 23:51:10.739 2254-2254/com.example.activitylifecycletest D/MainActivity: onStop
當點擊返回鍵時,將會回到主頁面MainActivity,將會打印出:
05-27 23:52:25.919 2254-2254/com.example.activitylifecycletest D/MainActivity: onRestart
05-27 23:52:25.919 2254-2254/com.example.activitylifecycletest D/MainActivity: onStart
05-27 23:52:25.920 2254-2254/com.example.activitylifecycletest D/MainActivity: onResume
(2)這時候我們點擊Start DialogActivity按鈕,這是Android Monitor將會打?。?/p>
05-27 23:53:54.872 2254-2254/com.example.activitylifecycletest D/MainActivity: onPause
點擊返回鍵,返回主頁面MainActivity,將會打印出:
05-27 23:55:19.005 2254-2254/com.example.activitylifecycletest D/MainActivity: onResume
(3)那么當我們想退出該應用,我們將點擊返回鍵,返回手機的主頁面,這時候Android Monitor將會打印出:
05-27 23:57:23.672 2254-2254/com.example.activitylifecycletest D/MainActivity: onPause
05-27 23:57:24.336 2254-2254/com.example.activitylifecycletest D/MainActivity: onStop
05-27 23:57:24.336 2254-2254/com.example.activitylifecycletest D/MainActivity: onDestory
這就是整個Activity的生命周期,這個代碼實例將涵蓋這七個Activity的方法
大概我的理解就這么多,因為是小白剛學沒多久,所以我對于Activity生命周期理解甚淺,求各位大神前輩輕噴。