一探究竟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,我也想更好的和大家進行交流;喜歡的點個贊,我的公衆號也可以關注一下;

簡書地址

公衆號二維碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章