關于Activity的生命周期理解

最近學習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生命周期理解甚淺,求各位大神前輩輕噴。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容