天天看點

Activity啟動過程分析

Android的四大元件中除了BroadCastReceiver以外,其他三種元件都必須在AndroidManifest中注冊,對于BroadCastReceiver來說,它既可以在AndroidManifest中注冊也可以通過代碼來注冊,在調用方式上,Activity、Service和BroadCastReceiver需要借助Intent,而ContentProvider則無需借助Intent。

Activity是一種展示型元件,用于向使用者直接展示一個界面,并且可以接收使用者的輸入資訊進而進行互動,對于使用者來說,Activity就是一個Android應用的全部,這是因為其他三大元件對使用者來說都是不可感覺的。Activity的啟動由Intent觸發,其中Intent可以分為顯式Intent和隐式Intent,顯式Intent可以明确地指向一個Activity元件,隐式Intent則指向一個或多個目标Activity元件,當然也有可能沒有一個Activity元件處理這個Intent。

要分析Activity的啟動過程,就需要從startActivity方法開始分析,startActivity方法有好幾種重載方式,但是最終都會調用startActivityForResult方法,具體代碼如下:

在上面代碼中,要注意的是mMainThread.getApplicationThread()這個參數,它的類型是ApplicationThread,ApplicationThread是ActivityThread的一個内部類,其實可以知道的是,ApplicationThread和ActivityThread在Activity啟動過程中發揮着重要的作用。然後看下 mInstrumentation.execStartActivity方法,代碼如下:

從上面代碼中可以看出,啟動Activity真正的實作由ActivityManagerNative.getDefault()的startActivity方法來完成的,ActivityManagerService(簡稱AMS)繼承自ActivityManagerNative,而ActivityManagerNative繼承自Binder并實作了IActivityManager這個Binder接口,是以AMS也是一個Binder,它是IActivityManager的具體實作,其實ActivityManagerNative.getDefault()具體得到是AMS,在ActivityManagerNative中,AMS這個Binder對象采用單例模式對外提供,第一次調用它的get方法時它會通過create方法來初始化AMS這個Binder對象,在後續的調用中則直接傳回之前建立的對象。這個過程源碼如下:

看到其中的源碼,可以得知,Activity的啟動過程又轉移到AMS中,最終隻需要分析AMS中的startActivity方法即可。同時,我們也在execStartActivity方法中看到這麼一句:checkStartActivityResult(result, intent),直覺應該是啟動Activity的結果,具體實作如下:

作用很明顯,就是檢查啟動Activity的結果,當無法正确地啟動一個Activity時,這個方法會抛出異常資訊,最熟悉的錯誤就是<code>Unable to find explicit activity class</code>,<code>have you declared this activity in your AndroidManifest.xml?</code>,當啟動的Activity沒有在AndroidManifest中注冊時,就會抛出這個異常。

現在看AMS的startActivity這個方法:

從中可以看出,Activity的啟動過程又轉移到mActivityStarter.startActivityMayWait的方法上,在startActivityMayWait方法中又調用了startActivityLocked方法,然後startActivityLocked方法又調用了startActivityUncheckedLocked方法,最後調用了ActivityStack的resumeTopActivitiesLocked,此時啟動過程轉移到ActivityStack上。

總結一下,這其中走的流程圖如下:

Activity啟動過程分析

最終,通過源碼分析,從IApplicationThread聲明方法可以看出,内部包含了大量的啟動、停止Activity的接口,此外還包含了啟動和停止服務的接口。那麼IApplicationThread的實作者到底是什麼,答案就是ActivityThread内部的ApplicationThread,ApplicationThread的定義如下:

我們可以看到IInterface接口有個類型IBinder:

最終是通過Binder通信,系統為AIDL檔案自動生成的代碼,同時還有會一個ApplicationThreadProxy類,這個類其實AIDL檔案自動生成的代理類,進而最終Activity的啟動過程最終回到ApplicationThread中。ApplicationThread通過scheduleLaunchActivity方法啟動Activity。

具體實作很簡單,就是發送一個啟動Activity的消息交由Handler處理,交給H處理,這個H具體類的源碼:

在LAUNCH_ACTIVITY中,可以看到這麼一句handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"),最終是交由handleLaunchActivity方法實作,它的源碼是:

進而performLaunchActivity方法最終完成了Activity對象的建立和啟動過程,并且ActivityThread通過handleResumeActivity方法來調用被啟動Activity的onResume這一生命周期方法。

那麼performLaunchActivity方法主要完成如下幾件事:

從ActivityClientRecord中擷取啟動的Activity的元件資訊

通過Instrumentation的newActivity方法使用類加載器建立Activity對象

通過LoadedApk的makeApplication方法來嘗試建立Application對象。值得注意的是在makeApplication方法中如果Application已經被建立過了,那麼就不會再重複建立了,這也意味着一個應用隻有一個Application對象。同時,Application建立完畢後,系統會調用Application的onCreate方法。

建立ContextImpl對象并通過Activity的attach方法來完成一些重要資料的初始化

調用Activity的onCreate方法

源碼如下:

是以借用一張流程圖,總體流程時序:

Activity啟動過程分析

源于對掌握的Android開發基礎點進行整理,羅列下已經總結的文章,從中可以看到技術積累的過程。

1,Android系統簡介

2,ProGuard代碼混淆

3,講講Handler+Looper+MessageQueue關系

4,Android圖檔加載庫了解

5,談談Android運作時權限了解

6,EventBus初了解

7,Android 常見工具類

8,對于Fragment的一些了解

9,Android 四大元件之 " Activity "

10,Android 四大元件之" Service "

11,Android 四大元件之“ BroadcastReceiver "

12,Android 四大元件之" ContentProvider "

13,講講 Android 事件攔截機制

14,Android 動畫的了解

15,Android 生命周期和啟動模式

16,Android IPC 機制

17,View 的事件體系

18,View 的工作原理

19,了解 Window 和 WindowManager

20,Activity 啟動過程分析

21,Service 啟動過程分析

22,Android 性能優化

23,Android 消息機制

24,Android Bitmap相關

25,Android 線程和線程池

26,Android 中的 Drawable 和動畫

27,RecylerView 中的裝飾者模式

28,Android 觸摸事件機制

29,Android 事件機制應用

30,Cordova 架構的一些了解

31,有關 Android 插件化思考

32,開發人員必備技能——單元測試