1. 程式人生 > >淺談桌面啟動一個應用Activity

淺談桌面啟動一個應用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方法會執行。