在Android桌面Launcher原始碼淺析中介紹了Android的桌面程式Launcher是如何響應使用者點選事件並啟動App的,這篇文章繼續介紹App在Android系統層的啟動流程。
一、啟動流程
二、Launcher通知AndroidOS(使用者點選圖示)
2.1 Activity.java
frameworks/base/core/java/android/app/Activity.java 原始碼地址
- 在Android桌面Launcher原始碼淺析中提到
Launcher
最終透過frameworks/base/core/java/android/app/Activity.java
中的startActivity方法啟動了對應的應用程式。 startActivity
方法是透過呼叫startActivityForResult方法來實現的。startActivityForResult
方法最終呼叫了/frameworks/base/core/java/android/app/Instrumentation.java
的execStartActivity方法
public class Activity {
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
@Override
public void startActivityForResult(...) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// 呼叫Instrumentation的execStartActivity方法
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(...);
}
}
}
2.2 Instrumentation.java
frameworks/base/core/java/android/app/Instrumentation.java 原始碼地址
Instrumentation.java
中的execStartActivity方法是Activity啟動流程的關鍵。- execStartActivity方法透過ActivityTaskManager.getService().startActivity方法與系統服務進行通訊.
// Instrumentation中有多個execStartActivity同名方法,注意是target的型別為Activity的方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// ActivityTaskManager.getService()獲取到ActivityTaskManagerService的例項物件
// 呼叫ActivityTaskManagerService.startActivity
int result = ActivityTaskManager.getService()
.startActivity(...);
}
2.3 ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java 原始碼地址
ActivityTaskManagerService
是一個系統服務,負責管理Activity的啟動。- startActivity方法呼叫了startActivityAsUser方法
- startActivityAsUser方法透過
ActivityStartController
的obtainStarter方法獲取了ActivityStarter
物件例項,並呼叫ActivityStarter
的execute
方法
public final int startActivity(...) {
// 呼叫startActivityAsUser方法
return startActivityAsUser(...);
}
public final int startActivityAsUser(...) {
// ActivityStartController的obtainStarter獲取了ActivityStarter物件
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
... // 構造引數
.execute();
}
2.4 ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java 原始碼地址
- 在
ActivityStarter
中最終會呼叫RootWindowContainer
的resumeFocusedTasksTopActivities方法
int execute() {
// 呼叫executeRequest方法
res = executeRequest(mRequest);
}
private int executeRequest(Request request) {
// 建立ActivityRecord物件
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
... // 構造引數
.build();
// 呼叫startActivityUnchecked方法
mLastStartActivityResult = startActivityUnchecked(...);
}
private int startActivityUnchecked(...) {
// 呼叫startActivityInner
result = startActivityInner(...);
}
int startActivityInner(...) {
// 呼叫RootWindowContainer的resumeFocusedTasksTopActivities方法
mRootWindowContainer.resumeFocusedTasksTopActivities(...);
}
2.5 RootWindowContainer.java
/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java 原始碼地址
RootWindowContainer
是WindowManagerService的主要組成部分之一,是一個管理視窗的容器。- 呼叫
Task
和TaskFragment
將前臺程式Pause,為新的應用程式啟動做準備。 - 在resumeFocusedTasksTopActivities中呼叫
Task
的resumeTopActivityUncheckedLocked方法。
private boolean resumeFocusedTasksTopActivities(...) {
// 呼叫Task的resumeTopActivityUncheckedLocked方法
result = targetRootTask.resumeTopActivityUncheckedLocked(...);
}
2.5.1 Task.java
/frameworks/base/services/core/java/com/android/server/wm/Task.java 原始碼地址
- 在
Task
最終呼叫TaskFragment
的resumeTopActivity方法
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(...) {
// 呼叫resumeTopActivityInnerLocked
someActivityResumed = resumeTopActivityInnerLocked(...);
}
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(...) {
final TaskFragment topFragment = topActivity.getTaskFragment();
// 呼叫TaskFragment的resumeTopActivity
resumed[0] = topFragment.resumeTopActivity(...););
return resumed[0];
}
2.5.2 TaskFragment.java
/frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java 原始碼地址
- 在
TaskFragment
最終呼叫ActivityTaskManagerService
的startProcessAsync方法
final boolean resumeTopActivity(...) {
// 暫停當前視窗的Aciticity,可參見原始碼
...
// 呼叫ActivityTaskManagerService的startProcessAsync方法建立新的Activity
ActivityTaskManagerService的startProcessAsync方法
mAtmService.startProcessAsync(...);
}
2.6 再次回到ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java 原始碼地址
- 處理完視窗容器資料以後(核心工作是將前臺程式Pause),再次回到了
ActivityTaskManagerService
- 在startProcessAsync方法傳送非同步訊息,呼叫
ActivityManagerInternal
的startProcess方法 ActivityManagerInternal
的實現類是ActivityManagerService
// mAmInternal的獲取方法,註冊方法在ActivityManagerService中(下一小節2.8做介紹)
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
void startProcessAsync(...) {
// PooledLambda會自動呼叫mAmInternal(ActivityManagerInternal)的startProcess方法
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mAmInternal, ...);
mH.sendMessage(m);
}
- ActivityManagerInternal是一個抽象類,具體實現在
ActivityManagerService.java
中實現
2.7 ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 原始碼地址
- 在
ActivityManagerService
最終呼叫ProcessList
的startProcessLocked方法
public class ActivityManagerService extends IActivityManager.Stub {
// 初始化LocalService(ActivityManagerInternal)
private final ActivityManagerInternal mInternal = new LocalService();
public void init() {
// 在LocalServices中進行註冊
LocalServices.addService(ActivityManagerInternal.class, mInternal);
}
private class LocalService extends ActivityManagerInternal {
// ActivityManagerInternal 介面方法的具體實現
@Override
public void startProcess(...) {
synchronized (ActivityManagerService.this) {
// 呼叫ActivityManagerService的startProcessLocked方法
startProcessLocked(...)
}
}
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(...) {
// 呼叫ProcessList的startProcessLocked
return mProcessList.startProcessLocked(...);
}
}
2.7.1 ProcessList.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java 原始碼地址
- 在
ProcessList
最終呼叫到ZygoteProcess
的start方法
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, ...) {
// 定義建立Activity完成後回撥的入口點(重要)
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, ...);
}
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, ...) {
// 呼叫startProcess
final Process.ProcessStartResult startResult = startProcess(...);
}
private Process.ProcessStartResult startProcess(...) {
// 獲取AppZygote
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
// appZygote.getProcess()獲取到ChildZygoteProcess類(ZygoteProcess的子類)
// 呼叫ZygoteProcess的start方法
startResult = appZygote.getProcess().start(entryPoint,...);
}
2.8 ZygoteProcess.java
/frameworks/base/core/java/android/os/ZygoteProcess.java 原始碼地址
- 在
ZygoteProcess
傳送訊息給Zygote程序
,透過Zygote程序
建立新的activity程序
public final Process.ProcessStartResult start(...) {
// 呼叫startViaZygote
return startViaZygote(...)
}
private Process.ProcessStartResult startViaZygote(...) {
// 透過openZygoteSocketIfNeeded(abi)開啟一個到Zygote程序的套接字連線(Socket)。
// 呼叫zygoteSendArgsAndGetResult
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),zygotePolicyFlags,argsForZygote);
}
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(...) {
// 呼叫attemptZygoteSendArgsAndGetResult
return attemptZygoteSendArgsAndGetResult(...);
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(...) {
try {
// 建立Zygote套接字的輸入輸出流
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
// 傳送訊息給 Zygote 程序
zygoteWriter.write(msgStr);
zygoteWriter.flush();
// 讀取 Zygote 程序返回的結果
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
// 檢查 PID 是否有效
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
三、Activity程序建立(Zygote程序fork)
在Android啟動過程-萬字長文(Android14)介紹了Zygote程序(孵化器程序)
3.1 Zygote簡介
- Zygote程序是一個使用者程序,由init程序(1號程序)fork而來。
- Zygote程序透過fork的方式建立新的應用程式程序。
- Zygote程序的入口點是
ZygoteInit
類中的main方法。
下面將簡單介紹在Zygote程序的程式碼流轉。
3.2 ZygoteInit.java
Android14的ZygoteInit原始碼地址
Zygote
程序是在Android系統啟動過程中建立的,建立完成後會透過ZygoteServer
來監聽訊息
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
// 啟動Zygote伺服器,迴圈監聽訊息
caller = zygoteServer.runSelectLoop(abiList);
if (caller != null) {
// 有新的訊息就執行對應Runnable程式碼
caller.run();
}
...
}
3.3 ZygoteServer.java
Android14的ZygoteServer原始碼地址
- 在
ZygoteServer
獲取到訊息後會呼叫ZygoteConnection
的processCommand方法
Runnable runSelectLoop(String abiList) {
while (true) {
// 使用 select 監聽套接字
StructPollfd[] pollFDs = new StructPollfd[socketFDs.size()];
if (pollIndex == 0) {
// 接收到新的連線
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else {
// 處理已有連線的請求
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processCommand(this, multipleForksOK);
}
}
}
3.4 ZygoteConnection.java
Android14的ZygoteConnection原始碼地址
ZygoteConnection
的processCommand方法最終呼叫ZygoteInit
的zygoteInit方法
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
...
// 呼叫Zygote的forkAndSpecialize方法fork出Acitivity的程序
pid = Zygote.forkAndSpecialize(...);
if (pid == 0) {
// 在子程序中,即建立出來的應用程式所在程序
return handleChildProc(parsedArgs, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// 在父執行緒中,pid為建立好的子程序的id
handleParentProc(pid, serverPipeFd);
return null;
}
}
private void handleParentProc(int pid, FileDescriptor serverPipeFd) {
// 透過套接字Socket將子程序的 PID 返回給請求方(ActivityManagerService)
os.writeInt(pid);
}
private Runnable handleChildProc(...) {
// 子程序負責應用程式後續的初始化工作
ZygoteInit.zygoteInit(...)
}
- fork系統呼叫會建立一個新的程序(子程序)。在呼叫fork後,父程序和子程序(新建立出來的程序)會各自執行後續的程式碼。
- 在父程序中,fork返回子程序的PID。這是一個正整數,表示新建立的子程序的程序ID。
- 在子程序中(新程序),fork 返回 0。這表示當前程序是新建立的子程序。
- 應用程式(App)的程序就是新建立的子程序
3.5 再次回到ZygoteInit.java
Android14的ZygoteInit原始碼地址
- 呼叫
RuntimeInit.applicationInit
方法,進行應用程式的初始化過程
public static Runnable zygoteInit(...) {
// 常見的初始化工作,例如設定系統屬性、初始化預設的未捕獲異常處理器等
RuntimeInit.commonInit();
// Zygote相關的初始化工作。這個初始化過程在C/C++層面進行,設定了必要的Zygote執行環境
ZygoteInit.nativeZygoteInit();
// 呼叫RuntimeInit.applicationInit方法,進行應用程式的初始化過程
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader);
}
3.6 RuntimeInit.java
Android14的RuntimeInit原始碼地址
- 在
RuntimeInit
的applicationInit方法完成初始化工作後,透過反射的方式,呼叫android.app.ActivityThread
的main方法 - 引數列表中的startClass即
2.9 ProcessList.java
原始碼中的entryPoint(android.app.ActivityThread
)
protected static Runnable applicationInit(...) {
// 查詢並返回應用程式的主方法
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
private static Runnable findStaticMain(...) {
// 反射得到android.app.ActivityThread類
cl = Class.forName(className, true, classLoader);
// 反射獲取main方法
m = cl.getMethod("main", new Class[] { String[].class });
// 返回可被執行的Runnable物件
return new MethodAndArgsCaller(m, argv);
}
四、初始化Application例項
透過Zygote程序
fork出應用程式的程序後,下一步就是建立整個應用程式的Application例項
4.1 ActivityThread.java
Android14的ActivityThread原始碼地址
- 建立應用程式的ActivityThread例項
- 建立應用程式的Application例項
- 建立應用程式的Looper迴圈
public static void main(String[] args) {
// 初始化主線模組
initializeMainlineModules();
// 建立MainLooper
Looper.prepareMainLooper();
// 建立ActivityThread
ActivityThread thread = new ActivityThread();
// 建立應用程式Application例項
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 迴圈監聽訊息
Looper.loop();
}
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
// 獲取ActivityManagerService例項
final IActivityManager mgr = ActivityManager.getService();
// 呼叫ActivityManagerService的attachApplication方法
mgr.attachApplication(mAppThread, startSeq);
}
4.2 ActivityManagerService.java
Android14的ActivityManagerService原始碼地址
- 在
ActivityManagerService
完成Application建立和第一個Activity的建立
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
// 呼叫attachApplicationLocked方法
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
private void attachApplicationLocked(...) {
// 呼叫ActivityThread的bindApplication方法建立並繫結Application
thread.bindApplication(...)
// 在結束Application建立後呼叫finishAttachApplicationInner啟動app的第一個Activity頁面,在4.5會介紹這一部分程式碼
finishAttachApplicationInner(startSeq, callingUid, pid);
}
4.3 再次回到ActivityThread.java
Android14的ActivityThread原始碼地址
- 透過Handler機制完成訊息的傳遞,正式載入apk檔案
public final void bindApplication(...) {
AppBindData data = new AppBindData();
... // 構造data的資料
// H為Handler, BIND_APPLICATION是int值
sendMessage(H.BIND_APPLICATION, data);
}
// ActivityThread的內部類H
class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
}
}
}
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
Application app;
// 最終呼叫LoadedApk的makeApplicationInner方法載入apk檔案到記憶體中
app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
// 呼叫Application的onCreate方法,正式進入apk執行檔案
mInstrumentation.callApplicationOnCreate(app);
}
4.4 LoadedApk.java
Android14的LoadedApk原始碼地址
private Application makeApplicationInner(...) {
// 獲取app的application類(在AndroidManifast.xml中定義的),沒有就使用預設的android.app.Application
String appClass = mApplicationInfo.getCustomApplicationClassNameForProcess(
myProcessName);
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
// 呼叫Instrumentation的newApplication方法建立Application物件
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
}
4.5 Instrumentation.java
Android14的Instrumentation原始碼地址
- 在
Instrumentation
完成Application例項的初始化,並呼叫onCreate方法
// 建立Application物件
static public Application newApplication(Class<?> clazz, Context context) {
// Application例項的初始化
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
// 呼叫Application的onCreate方法
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
五、啟動第一個Activity
5.1 ActivityManagerService.java
Android14的ActivityManagerService原始碼地址
- 在執行完Application的onCreate方法後,我們再回到
ActivityManagerService.java
的attachApplicationLocked方法中 - 在attachApplicationLocked方法最終會呼叫
LocalService
的attachApplication方法來載入我們的第一個Acitivity頁面 ActivityTaskManagerInternal
是定義在ActivityTaskManagerService.java
的LocalService
類
private void attachApplicationLocked(...) {
// 呼叫ActivityThread的bindApplication方法建立並繫結Application
thread.bindApplication(...)
// 在結束Application建立後呼叫finishAttachApplicationInner啟動app的第一個Activity頁面
finishAttachApplicationInner(startSeq, callingUid, pid);
}
private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
if (normalMode) {
try {
// 呼叫`ActivityTaskManagerInternal`(即ActivityTaskManagerService.LocalService)的**attachApplication**方法來載入我們的第一個Acitivity頁面
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
}
}
}
5.2 ActivityTaskManagerService.java
Android14的ActivityTaskManagerService原始碼地址
- 在LocalService中呼叫
RootWindowContainer.attachApplication
方法
final class LocalService extends ActivityTaskManagerInternal {
@Override
public boolean attachApplication(WindowProcessController wpc){
// 呼叫RootWindowContainer的attachApplication
return mRootWindowContainer.attachApplication(wpc);
}
}
5.3 RootWindowContainer.java
Android14的RootWindowContainer原始碼地址
- 最終呼叫
ActivityTaskSupervisor
的realStartActivityLocked方法
boolean attachApplication(WindowProcessController app) throws RemoteException {
// 呼叫RootWindowContainer內部類AttachApplicationHelper的process方法
return mAttachApplicationHelper.process(app);
}
private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
boolean process(WindowProcessController app) throws RemoteException {
mApp = app;
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
// 透過/frameworks/base/services/core/java/com/android/server/wm/Task.java中的forAllRootTasks呼叫test方法
getChildAt(displayNdx).forAllRootTasks(this);
}
}
public boolean test(ActivityRecord r) {
// 呼叫ActivityTaskSupervisor的realStartActivityLocked方法
mTaskSupervisor.realStartActivityLocked(...)
}
}
5.3.1 Task.java
/frameworks/base/services/core/java/com/android/server/wm/Task.java原始碼地址
boolean forAllRootTasks(Predicate<Task> callback, boolean traverseTopToBottom) {
// 呼叫test方法
return isRootTask() ? callback.test(this) : false;
}
5.4 ActivityTaskSupervisor.java
Android14的ActivityTaskSupervisor原始碼地址
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// 建立ClientTransaction啟動事務:
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);
...
// 新增LaunchActivityItem回撥
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent...));
...
// 執行啟動事務,呼叫ClientLifecycleManager的scheduleTransaction方法
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
- ClientTransaction事務物件,用於描述一系列客戶端(即應用程序)需要執行的操作。
- LaunchActivityItem回撥引數中包括如何啟動Activity,啟動所需的Intent、配置、狀態等資訊。
5.4.1 ClientLifecycleManager.java
Android14的ClientLifecycleManager原始碼地址
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
// 呼叫ClientTransaction的schedule
transaction.schedule();
}
5.4.2 ClientTransaction.java
Android14的ClientTransaction原始碼地址
public void schedule() throws RemoteException {
// 呼叫mClient的scheduleTransaction方法
mClient.scheduleTransaction(this);
}
- mClient是
IApplicationThread
介面,實際是ActivityThread的內部類ApplicationThread
物件。 - mClient在
ActivityTaskSupervisor的realStartActivityLocked方法
中透過ClientTransaction.obtain(proc.getThread(), r.token),具體可參考ActivityTaskSupervisor原始碼
5.5 回到ActivityThread.java
Android14的ActivityThread原始碼地址
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
// 呼叫ActivityThread的scheduleTransaction
ActivityThread.this.scheduleTransaction(transaction);
}
}
- scheduleTransaction方法實際呼叫的是
ActivityThread父類ClientTransactionHandler
的scheduleTransaction方法
5.5.1 ClientTransactionHandler.java
Android14的ClientTransactionHandler原始碼地址
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
// 將事務放入訊息佇列中,等待主執行緒的處理
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
5.5.2 ActivityThread的內部Handler類H處理訊息
Android14的ActivityThread原始碼地址
public void handleMessage(Message msg) {
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
break;
}
}
5.5.3 TransactionExecutor.java
Android14的TransactionExecutor原始碼地址
public void execute(ClientTransaction transaction) {
// 執行事務中的回撥和生命週期狀態請求
executeCallbacks(transaction);
executeLifecycleState(transaction);
}
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
// 遍歷事務中的所有回撥項,並呼叫每個回撥項的execute方法。
for (int i = 0, size = callbacks.size(); i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
item.execute(mClient, mTransactionHandler, transaction.getLifecycleStateRequest());
}
}
- 每個回撥項的execute方法實際就是呼叫
LaunchActivityItem
的execute方法
5.5.4 LaunchActivityItem.java
Android14的LaunchActivityItem原始碼地址
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
client.handleLaunchActivity(new LaunchActivityItem.ActivityClientRecord(this), pendingActions, null);
}
- 呼叫ClientTransactionHandler即
ActivityThread
的handleLaunchActivity方法
5.6 回到ActivityThread
Android14的ActivityThread原始碼地址
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
// 呼叫performLaunchActivity
final Activity a = performLaunchActivity(r, customIntent);
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 建立activity物件
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
}
5.6.1 Instrumentation.java
Android14的Instrumentation原始碼地址
public Activity newActivity(...) {
// 建立Activity
Activity activity = (Activity)clazz.newInstance();
...
return activity;
}
5.6.2 回到ActivityThread的performLaunchActivity方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 建立activity物件
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
// activity繫結上下文Context
activity.attach(appContext, this, getInstrumentation(), r.token,...);
// 呼叫Instrumentation的callActivityOnCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
}
5.6.3 Instrumentation的callActivityOnCreate方法
public void callActivityOnCreate(Activity activity, Bundle icicle) {
// 呼叫Activity的performCreate方法
activity.performCreate(icicle);
}
5.7 Activity.java
Android14的Activity原始碼地址
- 在Activity中實現了生命週期方法的呼叫邏輯
5.7.1 onCreate方法
final void performCreate(...) {
// 呼叫onCreate方法
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
}
- 繞了一大圈,最終又回到了Activity.java
- 在performCreate中呼叫onCreate生命週期方法
5.7.2 onStart方法
5.7.2.1 TransactionExecutor.java
- 在TransactionExecutor.java的方法execute中透過executeCallbacks建立了Activity並呼叫onCreate方法
- 然後在executeLifecycleState方法中呼叫後續的生命週期方法
public void execute(ClientTransaction transaction) {
// 執行事務中的回撥
executeCallbacks(transaction);
// 執行生命週期
executeLifecycleState(transaction);
}
public void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem != null) {
// 呼叫ActivityLifecycleItem的execute方法
lifecycleItem.execute(transaction.getClientTransactionHandler(), token, pendingActions);
}
}
ActivityResultItem
是一個抽象類- 這裡實際呼叫的是
ActivityResultItem
的execute方法
5.7.2.2 ActivityResultItem.java
Android14的ActivityResultItem原始碼地址
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handleResumeActivity(token, true /* isForward */, "RESUME_ACTIVITY");
}
- 這裡實際呼叫的是
ActivityThread
的handleResumeActivity方法
5.7.2.3 ActivityThread的handleResumeActivity方法
Android14的ActivityThread原始碼地址
public void handleResumeActivity(IBinder token, boolean finalStateRequest, String reason) {
// 先呼叫ActivityThread的performStart方法
performRestartActivity(r);
// 再呼叫Activity的performResume
r.activity.performResume();
}
public void performRestartActivity(ActivityClientRecord r) {
// 呼叫Activity的performStart
r.activity.performStart();
}
5.7.2.4 Activity的performStart方法
Android14的Activity原始碼地址
final void performStart() {
// 呼叫Instrumentation的callActivityOnStart方法
mInstrumentation.callActivityOnStart(this);
}
5.7.2.5 Instrumentation的callActivityOnStart方法
Android14的Instrumentation原始碼地址
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
5.7.3 onResume方法
在5.7.2.3 ActivityThread的handleResumeActivity方法
中提到在onStart方法執行後會呼叫r.activity.performResume();
即Activity的performResume方法
5.7.3.1 Activity的performResume方法
Android14的Activity原始碼地址
final void performResume(boolean followedByPause, String reason) {
mInstrumentation.callActivityOnResume(this);
}
5.7.3.2 Instrumentation的callActivityOnResume方法
Android14的Instrumentation原始碼地址
public void callActivityOnResume(Activity activity) {
activity.onResume();
}
- 至此Activity建立完成,並完成了核心生命週期方法的建立
- 在onResume方法後,Activity進入前臺,準備顯示給使用者
六、 後續工作
在生命週期完成後,應用程式就會被展示在螢幕上,後續的工作主要是渲染,這裡做一個簡單的流程說明
- Activity例項化時建立一個Window物件,預設情況下是PhoneWindow。在PhoneWindow中,有一個 DecorView,它是整個檢視層次的根檢視。
- 在Activity的onCreate方法中,Activity會呼叫setContentView方法,將佈局資源載入到DecorView中
- WindowManager負責管理應用程式視窗,將DecorView新增到視窗中
- 當DecorView被新增到視窗中後。ViewRootImpl類負責檢視層次結構的測量(measure)、佈局(layout)和繪製(draw)
- 最終由SurfaceFlinger合成並顯示在螢幕上
以上就是應用程式啟動的全過程,如有錯漏,歡迎留言討論。