淺談桌面啟動一個應用Activity
startActivity
1、Launcher程序
Handler機制在主執行緒迴圈處理訊息,在onCreate時呼叫了startActivity,通過Binder程序間通訊機制傳送了START_ACTIVITY_TRANSATION。
START_ACTIVITY_TRANSATION:非同步請求,傳送完Launcher程序睡覺等待在主執行緒。
2、SystemServer
SystemServer執行緒向Launcher主執行緒傳送SCHEDULE_PAUSE_ACTIVITY_TRANSACTION(通過ApplicationThreadProxy),之所以選擇Launcher主執行緒,是因為Launcher主執行緒正在等待SystemServer的返回資料。這個過程是同步的,只發送不等待返回結果。
之後SystemServer執行緒向Launcher主執行緒傳送了START_ACTIVITY_TRANSATION的返回結果。
3、Launcher程序
Launcher程序此時需要處理兩個返回命令,一個是BR_TRANSATION(傳送SCHEDULE_PAUSE_ACTIVITY_TRANSACTION),一個是BR_REPLY(START_ACTIVITY_TRANSATION的返回結果)。
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { int32_t cmd; int32_t err; while (1) { if ((err=talkWithDriver()) < NO_ERROR) break; err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; cmd = mIn.readInt32();//讀取了BR_TRANSACTION_COMPLETE協議,mIn中就沒有資料了 ..... switch (cmd) { case BR_TRANSATION: .... break; case BR_REPLY: .... break; ..... } ........ return err; }
先處理BR_TRANSATION,向主執行緒的Handler傳送了H.PAUSE_ACTIVITY,此時由於onCreate在主執行緒中執行,所以這個命令還不能馬上執行。
再處理BR_REPLY,退出onCreate,繼續執行Handler裡面的內容H.PAUSE_ACTIVITY。向SystemServer傳送ACTIVITY_PAUSED_TRANSACTION,非同步請求,要求等待返回值。主執行緒繼續睡眠等待返回值。
4、SystemServer
SystemServer執行緒會執行Process.start,來請求Zygote fork出一個新的程序,新程序入口地址ActivityThread.main。然後SystemServer繼續執行,給Launcher主執行緒傳送返回值。
5、應用程式程序
從入口ActivityThread.main繼續執行,此時子執行緒用來處理binder程序間通訊,在handleChildProc-->zygoteInit已經建立了。但是此時Handler主執行緒迴圈機制並未建立。
public final class ActivityThread {
......
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}
......
}
應用程式主執行緒向SystemServer傳送ATTACH_APPLICATION_TRANSACTION,非同步請求,在主執行緒睡眠等待。6、SystemServer
SystemServer有一個執行緒來處理程序間通訊請求,通過ApplicationTheadProxy嚮應用程式主執行緒傳送BIND_APPLICATION_TRANSATION和SCHDULE_LAUNCH_ACTIVITY_TRANSATION同步請求。之所有選擇應用程式主執行緒,是因為他正在等待SystemServer的返回資料,不用白不用。
之後再想應用程式主執行緒傳送返回資料。
7、應用程式程序
應用程式主執行緒被喚醒,需要處理兩個BR_TRANSATION,一個BR_REPLY。
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = mIn.readInt32();//讀取了BR_TRANSACTION_COMPLETE協議,mIn中就沒有資料了
.....
switch (cmd) {
case BR_TRANSATION:
....
break;
case BR_REPLY:
....
break;
.....
}
........
return err;
}
先處理兩個BR_TRANSATION,分別向主執行緒Handler傳送兩個訊息,由於目前Handler機制尚未建立完成,待處理完BR_REPLY主執行緒繼續執行Looper.loop時,會執行。也就是應用程式程序的Application類的onCreate的方法和Activity類的onCreate方法會執行。