版本:27.1.1
流程圖
本文只做一個主線的分析。
先上activity啓動的流程總圖,分兩大塊分析:
- 程序啓動做了哪些事情?
- Activity加載以及完成它的聲明週期
程序的啓動
相關類 ActivityThrea、ActivityManager的主線流程圖
結合下面的源碼分析一起看理解效果更佳哦!
源碼分析
有看過源碼的android 朋友都應該熟悉,ActivityThread中的main方法是啓動點。下面看下main方法裏究竟做了什麼?
- main()
public static void main(String[] args) {
// ....省略N行代碼
// 得到ActivityThread實例如並調用 attach方法
ActivityThread thread = new ActivityThread();
thread.attach(false);
// ....省略N行代碼
}
- attach()
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {// true代表系統,false:應用
// ....省略N行代碼
// 獲取了 IActivityManager管理類 getService()請看 分析->getService()
final IActivityManager mgr = ActivityManager.getService();
try {
// 關聯ApplicationThread 分析->ApplicationThread
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// ....省略N行代碼
} else {
// ....省略N行代碼
}
}
// 分析->ApplicationThread
// 初始化ApplicationThread,存放activity的信息,以及提供一些有關activity聲明週期的方法
ApplicationThread mAppThread = new ApplicationThread()
// 這裏不帶貼具體源碼,會在activity加載以及完成生命週期的分析中貼出
// 分析->getService()
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
// 獲取binder對象。可以看出使用了binder通信機制
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 根據binder找到IActivityManager。結合上一行代碼可以看出ActivityManager是用系由統服務調用管理的
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
小結: 通過以上源碼可以確定,源碼中用到了binder通信機制
,由此可知ActivityManager管理類是由系統服務調用管理。這裏我們可以知道Activity是跨進程訪問的
。
最後會通過 mgr.attachApplication(mAppThread)
關聯ApplicationThread
到這裏主要的啓動已經完成,我們需要去關注ApplicationThread做了什麼?
請看下面分析!
Activity加載以及完成它的聲明週期
流程圖
相關類:ActivityThread內部類(ApplicationThread 、H)
、Instrumentation、Activity
- ApplicationThred提供Acivity的信息、啓動方法、發送消息
- H負責處理與activity相關啓動方法、相關生命週期的完成方法
- Instrumentation負責回調callActivityOnCreate() -> Activity的performCreate()->onCreat()方法
請結合下圖和對應的源碼分析
源碼分析
- ApplicationThread
源碼很多有關生命週期的方法,這裏只貼出一個啓動activity的方法
private class ApplicationThread extends IApplicationThread.Stub {
// ....省略N行代碼
// 啓動Activity的方法
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
// ....省略N行代碼
// 發送啓動activity消息
sendMessage(H.LAUNCH_ACTIVITY, r);
}
// ....省略N行代碼
}
由啓動方法的流程可知:
當Activity狀態發生變化時,會調用到這裏,有這裏發送Message消息進行通知狀態的的更新。
2. H
小結:由上面源碼可以看出,這裏啓動Activity是利用Handler通信機制完成
,
分析->handleLaunchActivity()
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// ...省略N行代碼
Activity a = performLaunchActivity(r, customIntent);
// ...省略N行代碼
}
分析->performLaunchActivity()
相信看到這裏就可以知道整個activity的啓動流程了
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// ...省略N行代碼
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// ...省略N行代碼
return activity;
}
後面就不再分析貼源碼了,後面的流程:callActivityOnCreate() -> activity.performCreate() -> onCreate();
總結
分析過程中的核心點:
- activity啓動使用了
Binder通信機制
- 啓動時以及activity的狀態發生變化時使用了
handler消息機制
整體流程核心步驟:
- 在ActivityThread的main方法裏,new出ActivityThread實例,然後調用
attach
去獲取IActivityManager管理類,然後調用attachApplication
實現IActivityManager與ApplicationThread的綁定 - IActivityManager的獲取:通過
ServiceManager.getService(Context.ACTIVITY_SERVICE)
得到一個Binder接口
,根據binder獲取返回的IActivityManager
- 根據ApplicationThread中相關activity的相關
啓動方法、生命週期完成方法
,完成調用 - ApplicationThread中相關方法調用時,通過
Handler機制
去通知相關activity狀態的更新 - 會在
H
類中的handleMessage
去處理這些消息,完成響應的操作
完結! 點個贊吧