android核心機制之Zygote啟動流程 – Android移動開發技術文章_手機開發 Android移動開發教學課程

Zygote實際上是一個進程繁殖器,通過socket的select模型進行繁殖.類似命令的方式來進行Fork.
下面繪制瞭其流程圖.
 
可以看到:
 
1.Zygote服務實際上是一種Select服務模型.
2.為瞭啟動java代碼,進行瞭一次androidRuntime的打開和關閉.
3.啟動的SystemServer進程,此進程啟動瞭一個線程註冊瞭很多服務之後,開啟瞭手機的HOME(也就是桌面),然後開始服務循環.(註意:此服務是Binder服務,Binder服務一啟動就是倆線程。可能是因為是兩個CPU吧。
代碼如下:
4.Zygote進入select循環系統,開始服務.
5.此服務是很簡單的,而且是通用的服務代碼。(也就是取數據,傳輸數據,與SOCKET有些類似)。上層必須基於此服務原型來寫相應的代碼。
 
Java代碼 
ProcessState::self()->startThreadPool();//啟動一個。 
IPCThreadState::self()->joinThreadPool();//把此線程也加入。 
 
Cpp代碼 
case BR_TRANSACTION: 
    { 
        binder_transaction_data tr; 
        result = mIn.read(&tr, sizeof(tr)); 
        LOG_ASSERT(result == NO_ERROR, 
            "Not enough command data for brTRANSACTION"); 
        if (result != NO_ERROR) break; 
         
        Parcel buffer; 
        buffer.ipcSetDataReference( 
            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), 
            tr.data_size, 
            reinterpret_cast<const size_t*>(tr.data.ptr.offsets), 
            tr.offsets_size/sizeof(size_t), freeBuffer, this); 
         
        const pid_t origPid = mCallingPid; 
        const uid_t origUid = mCallingUid; 
         
        mCallingPid = tr.sender_pid; 
        mCallingUid = tr.sender_euid; 
         
        int curPrio = getpriority(PRIO_PROCESS, mMyThreadId); 
        if (gDisableBackgroundScheduling) { 
            if (curPrio > ANDROID_PRIORITY_NORMAL) { 
                // We have inherited a reduced priority from the caller, but do not 
                // want to run in that state in this process.  The driver set our 
                // priority already (though not our scheduling class), so bounce 
                // it back to the default before invoking the transaction. 
                setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL); 
            } 
        } else { 
            if (curPrio >= ANDROID_PRIORITY_BACKGROUND) { 
                // We want to use the inherited priority from the caller. 
                // Ensure this thread is in the background scheduling class, 
                // since the driver won't modify scheduling classes for us. 
                // The scheduling group is reset to default by the caller 
                // once this method returns after the transaction is complete. 
                androidSetThreadSchedulingGroup(mMyThreadId, 
                                                ANDROID_TGROUP_BG_NONINTERACT); 
            } 
        } 
 
        //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid); 
         
        Parcel reply; 
        IF_LOG_TRANSACTIONS() { 
            TextOutput::Bundle _b(alog); 
            alog << "BR_TRANSACTION thr " << (void*)pthread_self() 
                << " / obj " << tr.target.ptr << " / code " 
                << TypeCode(tr.code) << ": " << indent << buffer 
                << dedent << endl 
                << "Data addr = " 
                << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer) 
                << ", offsets addr=" 
                << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl; 
        } 
        if (tr.target.ptr) { 
            sp<BBinder> b((BBinder*)tr.cookie); 
            const status_t error = b->transact(tr.code, buffer, &reply, 0); 
            if (error < NO_ERROR) reply.setError(error); 
             
        } else { 
            const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0); 
            if (error < NO_ERROR) reply.setError(error); 
        } 
         
        //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n", 
        //     mCallingPid, origPid, origUid); 
         
        if ((tr.flags & TF_ONE_WAY) == 0) { 
            LOG_ONEWAY("Sending reply to %d!", mCallingPid); 
            sendReply(reply, 0); 
        } else { 
            LOG_ONEWAY("NOT sending reply to %d!", mCallingPid); 
        } 
         
        mCallingPid = origPid; 
        mCallingUid = origUid; 
 
        IF_LOG_TRANSACTIONS() { 
            TextOutput::Bundle _b(alog); 
            alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj " 
                << tr.target.ptr << ": " << indent << reply << dedent << endl; 
        } 
         
    } 
    break; 
 

發佈留言