1. 程式人生 > >一探究竟Activity的過程

一探究竟Activity的過程

好像工作了這麼久,從來沒去追究過Android是從哪裡啟動的,所以最近帶著這個疑問來看了看原始碼。也和大家分享一下這個知識。

1.Activity是什麼?

Activity是Android元件中最基本也是最為常見用的四大元件之一。

2.Activity的生命週期?

下面的是常見的Activity的生命週期圖;

這裡寫圖片描述

Activity生命週期圖

Android的狀態的介紹:

onCreate: 表示Activity的建立,生命週期的第一個方法,可以在此方法中進行初始化的操作(載入佈局資源、初始化Activity所需要的資料等)切記,耗時的工作要建立非同步執行緒來完成;

onStart: 與onStop配對,表示Activity正在被啟動,並且即將開始。但是這個時候要注意它與onResume的區別。兩者都表示Activity可見,但是onStart時Activity還正在載入其他內容,正在向我們展示,使用者還無法看到,即無法互動。

onRestart: 表示Activity正在重新啟動。一般情況下,在當前Activity從不可見重新變為可見的狀態時onRestart就會被呼叫。這種情形一般是由於使用者的行為所導致的,比如使用者按下Home鍵切換到桌面或者打開了一個新的Activity(這時當前Activity會暫停,也就是onPause和onStop被執行),接著使用者有回到了這個Activity,就會出現這種情況。

onResume: 與onPause配對,表示Activity已經建立完成,並且可以開始活動了,這個時候使用者已經可以看到介面了,並且即將與使用者互動(完成該週期之後便可以響應使用者的互動事件了)。

onPause: 與onResume配對,表示Activity正在暫停,正常情況下,onStop接著就會被呼叫。在特殊情況下,如果這個時候使用者快速地再回到當前的Activity,那麼onResume會被呼叫(極端情況)。一般來說,在這個生命週期狀態下,可以做一些儲存資料、停止動畫的工作,但是不能太耗時,如果是由於啟動新的Activity而喚醒的該狀態,那會影響到新Activity的顯示,原因是onPause必須執行完,新的Activity的onResume才會執行。

onStop: 表示Activity即將停止,可以做一些稍微重量級的回收工作,同樣也不能太耗時(可以比onPause稍微好一點)。

onDestroy: 與onCreate配對,表示Activity即將被銷燬,這是Activity生命週期的最後一個回撥,我們可以做一些回收工作和最終的資源釋放(如Service、BroadReceiver、Map等)。

下面做一些簡單的分析和生命週期的啟動方式:

1.正常建立一個activity的生命週期:

onCreate—>onStart—>onResume

這裡寫圖片描述

正常啟動Activity的生命週期方法呼叫

2.當用戶按返回鍵後的生命週期

onPause—>onStop—>onDestroy

這裡寫圖片描述

點選返回鍵正常Activity退出的生命週期方法呼叫

3.點選MainActivity中button啟動另外的SecondActivity的時候,生命週期呼叫方法

MainActivity生命週期的onPause—>SecondActivity的onCreate—>SecondActivity的onStart—>SecondActivity的onResume—>MainActivity的onStop

這裡寫圖片描述

點選按鈕啟動另外的activity的生命週期方法

4.在上面的情境下,我們推出SecondActivity,看看兩個生命週期的變化如何?

SecondActivity: onPause—>MainActivity: onRestart—>MainActivity: onStart—>MainActivity: onResume—>SecondActivity: onStop—>SecondActivity:onDestroy

這裡寫圖片描述

退出SecondActivity的生命週期方法

5.現在看看一個activity的切換橫豎螢幕的時候生命週期變化,當前為豎屏,切換橫屏

MainActivity: onPause—>MainActivity: onStop—>MainActivity: onDestroy—>MainActivity: onCreate—>MainActivity: onStart—>MainActivity: onResume
這裡寫圖片描述
切換橫豎屏的時候的生命週期方法

切換橫豎螢幕的時候,生命週期銷燬又重新建立了,這個是我們大多數情況下很不願意看見的啊,如何才能不讓其生命週期發生變化呢?

1.在AndroidMe.xml 的標籤中增加android:configChanges=”orientation|keyboardHidden|screenSize”

2.禁止豎屏或者禁止橫屏

在AndroidManifest.xml的activity中加入:

橫屏:android:screenOrientation=”landscape”

豎屏:android:screenOrientation=”portrait”

3.還可以在activity中重寫onConfigurationChanged方法;(詳情就不介紹了)

3.Activity的啟動模式及應用場景?

1)Standard模式:預設模式,會在啟動時建立一個新例項,建立的模式也可以隨Intent.FLAG_ACTIVITY_NEW_TASK而改變。

應用場景:絕大多數Activity。

2)SingleTop模式:當啟動activity時,有相同的activity在前臺與使用者互動,那就複用這個activity,這個例項會被呼叫Activity.onNewIntent()。

應用場景:在通知欄點選收到的通知,然後需要啟動一個Activity,這個Activity就可以用singleTop,否則每次點選都會新建一個Activity。

3)SingleTask模式:在啟動activity時,若有一個執行著這個activity的task,那這個activity例項會被調到前臺,並呼叫Activity.onNewIntent() ,啟動例項的Intent的flag會被設定Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT 。

應用場景:大多數App的主頁

4)SingleInstance模式:開闢一個只允許一個activity例項在裡頭執行的task. 如果用同樣的intent再次啟動這個activity,task會被調到前臺,其Activity.onNewIntent() 會被呼叫. 如果這個activity例項要啟動一個新activity,那麼這個新activity會在一個新task中執行。

應用場景:呼叫來電介面。這種模式的使用情況比較罕見,在Launcher中可能使用。或者你確定你需要使Activity只有一個例項。建議謹慎使用。

4.Activity的啟動過程?

    啟動過程,那就是講Android應用是如何啟動的,簡單的描述一下,點選手機中的應用圖示,這樣,這個應用就啟動起來了。

   看似很簡單的,實則這個過程很是複雜,下面我就從原始碼的角度給大家分享一下我所看到的吧(有什麼不對之處請指出);

點選圖示啟動,實則是啟動了一個Launcher.java的類,這個類繼承了Activity類。
Launcher.java中的onCreate方法一
Launcher.java中的onCreate方法一

這個方法有點長,暫時用2個圖來表達:看到內部的上面一些初始化和一些條件的判斷,我們主要看下面的這個地方;在圖二的下方有兩個方法(showFirstRunActivity和showFirstRunClings) 我們看看這兩個方法中做了什麼?
showFirstRunActivity

如圖所示,是不是看到我們所熟悉的startActivity方法呢,這個是啟動一個activity的方法,看看他的內部實現吧;

Activity類中的startActivity方法

startActivity

實現了內部的startActivity方法,2個引數,看看下面的實現,這可是一個追蹤的過程;
2引數的
startActivityForResult
startActivityForResult

追蹤到這裡,看看具體實現內容:

好像和這個Instrumentation類有關係,看看這個吧,找到這個類中的execStartActivity方法看看
execStartActivity

a).ActivityManagerNative.getDefault().startActivity 這個方法看來是真正執行啟動activity的東西
b).在execStartActivity中還看到一個檢查方法checkStartActivityResult;
checkStartActivityResult

想必從這個開始,就開啟了一個應用的啟動過程了。並不要以為這個就完了,下面我們要看看程式的入口在哪裡了;

5.Android程式的入口
類比一下,java的程式入口是main方法,那我們Android的程式入口在哪裡呢?
直接來講吧,看看ActivityThread.java這個類,在這個類中發現了main方法;豁然開朗啊,激動的淚花都出來了;
main方法

在ActivityThread方法中,看看thread.attach方法
ActivityManagerNative
IActivityManager是什麼呢?真的是破案,一點一點追蹤,下面再找找這個類;
IActivityManager是個介面,我們看看他的實現方法ActivityManagerNative.getDefault()這個;
gDefault.get()

get方法,我找找gDefault 是Singleton抽象類的抽象方法,好像又回到了最初
Singleton

還是看看抽象類中的實現吧;
Singleton gDefault

還是得看看IActivityManager中的實現方法 asInterface這個方法,具體看下圖
asInterface

最終返回值是ActivityManagerProxy 類,這個類是ActivityManagerNative 類的內部實現類了;

ActivityManagerNative 實現了一個IBinder,看到這裡,我後面會單獨的研究IBinder方法;
IBinder

寫到這裡,忽然不知道如何向下繼續,IBinder這個很複雜,單獨的抽出來一節來講吧,瞭解了Activity的啟動,生命週期,入口等,我希望可以幫助大家更好的理解activity,我也想更好的和大家進行交流;喜歡的點個贊,我的公眾號也可以關注一下;

簡書地址

公眾號二維碼