Android啟動(dòng)流程分析(4)-launcher進(jìn)程

前言

在system_server進(jìn)程啟動(dòng)的流程中秘噪,system_server在啟動(dòng)其他服務(wù)的流程中狸吞,會(huì)去調(diào)用AMS的systemReady()方法,上一篇說這部分就會(huì)去啟動(dòng)launcher應(yīng)用和和系統(tǒng)ui指煎,然后這一篇就分析一下launcher應(yīng)用的具體啟動(dòng)流程蹋偏。

在系統(tǒng)服務(wù)的引導(dǎo)服務(wù)中,會(huì)啟動(dòng)PMS服務(wù)至壤,PMS服務(wù)會(huì)去掃描檢測(cè)手機(jī)中的系統(tǒng)應(yīng)用和用戶安裝的非系統(tǒng)應(yīng)用威始,launcher應(yīng)用也是在PMS啟動(dòng)階段進(jìn)行掃描,并將其清單文件對(duì)應(yīng)的信息解析完成崇渗,在后續(xù)調(diào)用AMS的systemReady()方法字逗,launcher應(yīng)用的信息已經(jīng)解析完成了

#ActivityManagerService.java
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
            t.traceBegin("resumeTopActivities");
            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
            t.traceEnd();
    }

mAtmInternal就是AMS中持有的ATMS的binder引用,就會(huì)執(zhí)行到ATMS的resumeTopActivities

//#ActivityTaskManagerService.java
public void resumeTopActivities(boolean scheduleIdle) {
            synchronized (mGlobalLock) {
              //會(huì)執(zhí)行RootWindowContainer的對(duì)應(yīng)方法
                mRootWindowContainer.resumeFocusedStacksTopActivities();
                if (scheduleIdle) {
                    mStackSupervisor.scheduleIdle();
                }
            }
        }

//RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
            if (!resumedOnDisplay) {
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    //進(jìn)入這個(gè)流程
                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                } else if (targetStack == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
                }
            }
        }
        return result;
    }

//ActivityStack.java
//step1
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        boolean result = false;
        try {
            mInResumeTopActivity = true;
            //執(zhí)行這個(gè)方法
            result = resumeTopActivityInnerLocked(prev, options);
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
        } finally {
        }

        return result;
    }
//step2
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
      if (!hasRunningActivity) {
            // There are no activities left in the stack, let's look somewhere else.
            //Launcher應(yīng)用進(jìn)程啟動(dòng)之前是沒有activity的宅广,會(huì)繼續(xù)執(zhí)行
            return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
        }
}
//step3
private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
            ActivityOptions options) {
        final String reason = "noMoreActivities";
        //launcher應(yīng)用啟動(dòng)就是執(zhí)行這個(gè)關(guān)鍵的resumeHomeActivity方法
            //又回到了RootWindowContainer.java類
        return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea());
}

//RootWindowContainer.java
ActivityTaskManagerService mService;//成員屬性可以看出這個(gè)mService就是ATMS

boolean resumeHomeActivity(ActivityRecord prev, String reason,
            TaskDisplayArea taskDisplayArea) {
        final ActivityRecord r = taskDisplayArea.getHomeActivity();
        final String myReason = reason + " resumeHomeActivity";

            //繼續(xù)調(diào)用執(zhí)行
        return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
                false /* allowInstrumenting */, false /* fromHomeKey */);
}

boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
            boolean allowInstrumenting, boolean fromHomeKey) {
            //獲取ATMS的startController葫掉,去啟動(dòng)launcher
        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
                taskDisplayArea);
        return true;
    }

通過一系列的狀態(tài)判斷和方法調(diào)用,最終會(huì)回到跟activity管理密切相關(guān)的ATMS類跟狱,去執(zhí)行ActivityStartController類中的啟動(dòng)方法

#ActivityStartController.ava
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
            TaskDisplayArea taskDisplayArea) {
            //獲取ActivityStarter的實(shí)例俭厚,去執(zhí)行execute方法
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
    }
//通過obtainStarter去獲取一個(gè)ActivityStarter實(shí)例
ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

其他launcher應(yīng)用的啟動(dòng)會(huì)執(zhí)行到ActivityStarter類的execute方法,從類名上看驶臊,這就是一個(gè)專注于啟動(dòng)activity的類挪挤,跟應(yīng)用開發(fā)的關(guān)系還是很密切,繼續(xù)往后續(xù)代碼看

#ActivityStarter
//step1
int execute() {
        try {
            int res;
            synchronized (mService.mGlobalLock) {
                //上面的邏輯主要是對(duì)mRequest參數(shù)進(jìn)行一些狀態(tài)缺省判斷
                //下一步的主要執(zhí)行邏輯
                res = executeRequest(mRequest);//step2
                return getExternalResult(mRequest.waitResult == null ? res
                        : waitForResult(res, mLastStartActivityRecord));
            }
        } finally {
        }
    }

//step2
private int executeRequest(Request request) {
            //會(huì)創(chuàng)建兩個(gè)ActivityRecord對(duì)象关翎,Activity的啟動(dòng)是會(huì)傳當(dāng)前的context扛门,方便activity的棧的管理
        ActivityRecord sourceRecord = null;//from
        ActivityRecord resultRecord = null;//to
  
            //后續(xù)的執(zhí)行邏輯,前面就是對(duì)參數(shù)的各種處理邏輯
            //step3
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        return mLastStartActivityResult;
}

//step3
private int startActivityUnchecked() {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            //step4
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {}
  
        return result;
    }

//step4
int startActivityInner() {
   //launcher啟動(dòng)的關(guān)鍵方法
   mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
}

//step5
#RootWindowContainer.java
boolean resumeFocusedStacksTopActivities() {
         result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
     return result;
}

//step6
#ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
   boolean result = false;
   result = resumeTopActivityInnerLocked(prev, options);
     return result;
}

//step7
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        mStackSupervisor.startSpecificActivity(next, true, false);
}

//step8
#ActivityStackSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
            //這個(gè)用來獲取需要啟動(dòng)的activity的進(jìn)程纵寝,看進(jìn)程是否存在
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                //應(yīng)用進(jìn)程存在论寨,執(zhí)行這個(gè)方法
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {}
            knownToBeDead = true;
        }
        final boolean isTop = andResume && r.isTopRunningActivity();
        //如果應(yīng)用進(jìn)程不存在,執(zhí)行這個(gè)方法,去通知zygote符合新的進(jìn)程
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

通過上面一些列的方法調(diào)用葬凳,最終會(huì)執(zhí)行到判斷進(jìn)程是否存在的啟動(dòng)Activity的邏輯绰垂,這部分跟應(yīng)用進(jìn)程里面startactivity流程相關(guān)

目前的流程分析是通過system_server進(jìn)程去啟動(dòng)launcher進(jìn)程,那么launcher進(jìn)程就是不存在的火焰,就會(huì)執(zhí)行到ActivityTaskManagerService的startProcessAsync創(chuàng)建進(jìn)程的方法

#ActivityTaskManagerService.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        try {
            // ATMS lock held.
           //這類會(huì)通過handler去發(fā)生一個(gè)message
           //message里面攜帶的參數(shù)就是需要執(zhí)行的邏輯
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {}
    }

當(dāng)應(yīng)用進(jìn)程不存在的時(shí)候劲装,ATMS中會(huì)通過handler和messge機(jī)制進(jìn)行消息傳遞,消息的內(nèi)容就是需要執(zhí)行的邏輯(ActivityManagerInternal::startProcess)昌简,那這個(gè)就會(huì)執(zhí)行到AMS的方法中

#ActivityManagerService
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            try {
                synchronized (ActivityManagerService.this) {
                    // preempted by other processes before attaching the process of top app.
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName, isTop),
                            ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                            false /* isolated */, true /* keepIfLarge */);
                }
            } finally {}
        }

//繼續(xù)調(diào)用到這個(gè)方法
final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
                    //下一步執(zhí)行
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                keepIfLarge, null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }

#ProcessList.java
 boolean startProcessLocked() {
         try {
                 //注意這里的傳入?yún)?shù)的全類目占业,后續(xù)的啟動(dòng)中會(huì)用到  
                 final String entryPoint = "android.app.ActivityThread";

                    //下一步會(huì)執(zhí)行startProcess,啟動(dòng)進(jìn)程
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {}
  
            return app.pid > 0;
}

//進(jìn)一步調(diào)用會(huì)執(zhí)行到Process.java類的start方法
private Process.ProcessStartResult startProcess() {
                   startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                        whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
   
 }

#Process.java
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

public static ProcessStartResult start() {
            //參數(shù)很多就省略了纯赎,方便觀看執(zhí)行邏輯
            //會(huì)執(zhí)行到ZygoteProcess.java的start方法
        return ZYGOTE_PROCESS.start();
    }
  • 這里需要注意纺酸,傳入的參數(shù)全類目是"android.app.ActivityThread"

接下來就會(huì)執(zhí)行到ZygoteProcess的start()方法

#ZygoteProcess.java
public final Process.ProcessStartResult start(...) {
        try {
            //繼續(xù)執(zhí)行到startViaZygote方法
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
        }
}

 private Process.ProcessStartResult startViaZygote(...){
    ArrayList<String> argsForZygote = new ArrayList<>();
            //跟forkSystemServer一樣,會(huì)添加一些的啟動(dòng)參數(shù)
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
            ...
   
         //進(jìn)程的名稱屬性
       if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }
   
       synchronized(mLock) {
         //設(shè)置完屬性后乐严,就會(huì)調(diào)用此方法
         //第一個(gè)參數(shù)openZygoteSocketIfNeeded碳竟,從名字可以看出是通過socket跟zygote進(jìn)程通信
         return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
 }

我們前面知道所有的應(yīng)用進(jìn)程跟system_server進(jìn)程一樣,都是由zygote進(jìn)程fork生成的,而且在zygote進(jìn)程中會(huì)有一個(gè)socket等待消息的通知去處理生成新的進(jìn)程霉旗,執(zhí)行到這一步,就能跟前面的流程關(guān)聯(lián)起來了

#ZygoteProcess.java
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            attemptConnectionToPrimaryZygote();
                        //primary跟下面的secondary就是zygote流程中提到的64位和32位的兼容模式
            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }

            if (mZygoteSecondarySocketAddress != null) {
                attemptConnectionToSecondaryZygote();
                if (secondaryZygoteState.matches(abi)) {
                    return secondaryZygoteState;
                }
            }
        } catch (IOException ioe) {
        }
}

//啟動(dòng)主位數(shù)zygote連接
private void attemptConnectionToPrimaryZygote() throws IOException {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            //這里可以看出后續(xù)的執(zhí)行流程就是去調(diào)用connect方法建立socket連接
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
        }
}

//兼容位數(shù)的zygote連接戒努,代碼邏輯跟上面一致
private void attemptConnectionToSecondaryZygote() throws IOException {
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            secondaryZygoteState =
                    ZygoteState.connect(mZygoteSecondarySocketAddress,
                            mUsapPoolSecondarySocketAddress);
        }
}

//建立連接
static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
                @Nullable LocalSocketAddress usapSocketAddress)
                throws IOException {

                  //創(chuàng)建當(dāng)前進(jìn)程的socket對(duì)象
            final LocalSocket zygoteSessionSocket = new LocalSocket();

            try {
                //建立連接
                zygoteSessionSocket.connect(zygoteSocketAddress);
                //輸入輸出流對(duì)象創(chuàng)建
                zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
                zygoteOutputWriter =
                        new BufferedWriter(
                                new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
                                Zygote.SOCKET_BUFFER_SIZE);
            } catch (IOException ex) {}

            return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
                                   zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
                                   getAbiList(zygoteOutputWriter, zygoteInputStream));
        }

通過這一系列的操作就創(chuàng)建好了當(dāng)前進(jìn)程的Socket對(duì)象和輸入輸出流對(duì)象千扶,接下來就要通過這個(gè)socket通道去進(jìn)行消息的發(fā)送了,往上回一步秃嗜,創(chuàng)建socket對(duì)象是方法的第一個(gè)參數(shù)权均,就回到對(duì)應(yīng)的方法部分

#ZygoteProcess.java
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
            //處理參數(shù)
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";

        if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
            try {
                //執(zhí)行到這個(gè)方法
                return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
            } catch (IOException ex) {}
        }

        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }

private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr)
            throws ZygoteStartFailedEx, IOException {
        try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
            final BufferedWriter usapWriter =
                    new BufferedWriter(
                            new OutputStreamWriter(usapSessionSocket.getOutputStream()),
                            Zygote.SOCKET_BUFFER_SIZE);
            final DataInputStream usapReader =
                    new DataInputStream(usapSessionSocket.getInputStream());

            //這個(gè)地方就是進(jìn)行消息的寫入和發(fā)送
            usapWriter.write(msgStr);
            usapWriter.flush();

            Process.ProcessStartResult result = new Process.ProcessStartResult();
            result.pid = usapReader.readInt();
          
            if (result.pid >= 0) {
                return result;
            } else {
            }
        }
    }
小結(jié)

到這一步我們從systemServer進(jìn)程的啟動(dòng)其他服務(wù)的流程中,走到AMS的systemReady方法锅锨,然后AMS里面去一些的調(diào)用啟動(dòng)topActivity叽赊,發(fā)現(xiàn)APP進(jìn)程不存在,就通過AMS創(chuàng)建socket對(duì)象跟Zygote進(jìn)程連接并發(fā)送消息必搞,在Zygote進(jìn)程中必指,我們前面分析了創(chuàng)建了socket通道,并會(huì)進(jìn)入循環(huán)等待消息的到來恕洲,到這一步塔橡,就需要就分析Zygote進(jìn)程循環(huán)等待消息后,接收到消息的處理霜第,去fork新的app進(jìn)程
上面涉及的類比較多葛家,附上對(duì)應(yīng)的流程圖


啟動(dòng)app進(jìn)程給zygote進(jìn)程發(fā)消息的流程圖.jpg
#ZygoteInit.java
public static void main(String argv[]) {
    zygoteServer = new ZygoteServer(isPrimaryZygote);
    if (startSystemServer) {
      //之前分析到這,啟動(dòng)systemserver進(jìn)程
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);  //fork systemserver

       if (r != null) {
          r.run();
          return;
         }
    }

    caller = zygoteServer.runSelectLoop(abiList);  //zygote 進(jìn)程進(jìn)入無限循環(huán)泌类,處理請(qǐng)求
}

Runnable runSelectLoop(String abiList) {
     while (true) {
       
            int pollReturnValue;
            try {
                //通過epoll機(jī)制進(jìn)行循環(huán)等待
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);  //等到事件到來
            } catch (ErrnoException ex) {
            }
       
           if (pollReturnValue == 0) {

            } else {
             //有消息來了
                boolean usapPoolFDRead = false;

                //注意這里是倒序的癞谒,即優(yōu)先處理已建立鏈接的信息,后處理新建鏈接的請(qǐng)求
                while (--pollIndex >= 0) {
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }

                    //server socket 最新加入 fds, 因此這里就是 server socket 收到數(shù)據(jù)
                    if (pollIndex == 0) {
                        // Zygote server socket

                        //收到新的建立通信的請(qǐng)求,建立通信連接
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        //加入到 peers 和 socketFDs,即下一次也開始監(jiān)聽
                        peers.add(newPeer);
                        socketFDs.add(newPeer.getFileDescriptor());

                    } else if (pollIndex < usapPoolEventFDIndex) {   //其他通信連接收到數(shù)據(jù)
                        // Session socket accepted from the Zygote server socket
                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            //接收到請(qǐng)求后的具體執(zhí)行邏輯
                            final Runnable command = connection.processOneCommand(this);
                        }
                    }
                }
           }
     }
}

//接下來會(huì)執(zhí)行到ZygoteConnection的processOneCommand方法
#ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
    int pid;
    //通過forkAndSpecialize去fork出新的進(jìn)程
    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
  
   try {
            if (pid == 0) {
                // in child
                zygoteServer.setForkChild();
               //跟systemserver進(jìn)程一樣扯俱,由zygote孵化來的子進(jìn)程都需要關(guān)閉socket連接书蚪,釋放資源
                zygoteServer.closeServerSocket();
                //返回的最終執(zhí)行的runnable
                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            }
        }
}

//后續(xù)的孵化流程就跟啟動(dòng)systemserver類似
#Zygote.java
static int forkAndSpecialize(){
   //system_server: nativeForkSystemServer
   int pid = nativeForkAndSpecialize();
}

#com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(){
   //這個(gè)方法就是跟systemserver進(jìn)程的孵化方法一致了
   pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
}

//生成需要執(zhí)行的Runnable
#ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        closeSocket();
        Zygote.setAppProcessName(parsedArgs, TAG);

        if (parsedArgs.mInvokeWith != null) {
        } else {
            if (!isZygote) {
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            } else {
                return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            }
        }
    }

到這一步,AMS就通過zygote啟動(dòng)了launcher應(yīng)用進(jìn)程迅栅,從這可以看出殊校,啟動(dòng)systemserver進(jìn)程和普通的應(yīng)用進(jìn)程都是由zygote去進(jìn)行了,大體流程也是類似的读存,返回了Runable對(duì)象后會(huì)去執(zhí)行run方法为流,接下來的ZygoteInit.zygoteInit()就是在SystemServr啟動(dòng)流程中有分析過的方法

->ZygoteInit.zygoteInit()
->RuntimeInit.applicationInit()
->findStaticMain()

而在后續(xù)的流程中,就是通過反射去執(zhí)行對(duì)應(yīng)類的main方法让簿,在forkSystemServer方法中敬察,最終執(zhí)行的就是SystemServer.main(),而啟動(dòng)應(yīng)用進(jìn)程尔当,我們?cè)貾rocessList.java類中啟動(dòng)進(jìn)程莲祸,傳入的參數(shù)就是android.app.ActivityThread",所以launcher應(yīng)用的啟動(dòng)后續(xù)就會(huì)去執(zhí)行ActivityThread.main()方法

小結(jié)

通過一些列的流程分析,走到了我們熟悉的ActivityThread.main()方法椭迎,這個(gè)方法就是應(yīng)用進(jìn)程啟動(dòng)的入口锐帜,里面就會(huì)是執(zhí)行主線程的looper的啟動(dòng),執(zhí)行application.oncreat()方法等畜号,具體的launcher應(yīng)用的創(chuàng)建和顯示缴阎,和普通的app應(yīng)用流程一樣的,后續(xù)會(huì)分析PMS解析應(yīng)用四大組件后再分析app的啟動(dòng)到顯示到桌面的流程

點(diǎn)擊桌面圖標(biāo)的流程和launcher啟動(dòng)流程也是一樣的简软,通過AMS跟zygote建立socket連接蛮拔,發(fā)送消息后,zygote會(huì)判斷當(dāng)進(jìn)程不存在時(shí)去孵化新的應(yīng)用進(jìn)程痹升,然后再執(zhí)行對(duì)應(yīng)的ActivityThread.main()方法建炫,重復(fù)的話有點(diǎn)多,涉及到的類和方法調(diào)用鏈也很多视卢,梳理一遍對(duì)整個(gè)流程有一個(gè)更清晰的認(rèn)識(shí)

啟動(dòng)流程的分析踱卵,有點(diǎn)感覺像是記流水賬一樣,類之間的方法相互調(diào)用据过,看幾遍都不一定能記得住惋砂,我感覺也不需要記住,跟app應(yīng)用層開發(fā)關(guān)聯(lián)性不大
但是绳锅,必要的流程還是需要梳理清楚西饵,知道進(jìn)程之間的關(guān)系,加深對(duì)整個(gè)Android系統(tǒng)的認(rèn)知鳞芙,比如梳理完流程后眷柔,就能很清楚的認(rèn)知app進(jìn)程的孵化是需要zygote進(jìn)程去調(diào)用native的fork期虾,app進(jìn)程的啟動(dòng)又是需要AMS進(jìn)行發(fā)起,和zygote的通信是通過socket的方式發(fā)送消息驯嘱,在AMS中有ActivityStarter類會(huì)判斷進(jìn)程是否存在镶苞,分發(fā)不同的邏輯,應(yīng)用進(jìn)程的啟動(dòng)會(huì)執(zhí)行到ActivityThread.main()方法鞠评,不同的系統(tǒng)服務(wù)在SystemServer進(jìn)程中初始化啟動(dòng)茂蚓,并且有SystemServiceManager進(jìn)行生命周期的管理等

如果感興趣的朋友也可以跟我一樣跟著系統(tǒng)源碼一個(gè)方法一個(gè)方法的跟一下,加強(qiáng)自己吹逼的能力和知識(shí)儲(chǔ)備

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剃幌,一起剝皮案震驚了整個(gè)濱河市聋涨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌负乡,老刑警劉巖牍白,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異抖棘,居然都是意外死亡茂腥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門切省,熙熙樓的掌柜王于貴愁眉苦臉地迎上來础芍,“玉大人,你說我怎么就攤上這事数尿。” “怎么了惶楼?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵右蹦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我歼捐,道長(zhǎng)何陆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任豹储,我火速辦了婚禮贷盲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剥扣。我一直安慰自己巩剖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布钠怯。 她就那樣靜靜地躺著佳魔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晦炊。 梳的紋絲不亂的頭發(fā)上鞠鲜,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天宁脊,我揣著相機(jī)與錄音,去河邊找鬼贤姆。 笑死榆苞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的霞捡。 我是一名探鬼主播坐漏,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼弄砍!你這毒婦竟也來了仙畦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤音婶,失蹤者是張志新(化名)和其女友劉穎慨畸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衣式,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寸士,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碴卧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弱卡。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖住册,靈堂內(nèi)的尸體忽然破棺而出婶博,到底是詐尸還是另有隱情,我是刑警寧澤荧飞,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布凡人,位于F島的核電站,受9級(jí)特大地震影響叹阔,放射性物質(zhì)發(fā)生泄漏挠轴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一耳幢、第九天 我趴在偏房一處隱蔽的房頂上張望岸晦。 院中可真熱鬧,春花似錦睛藻、人聲如沸启上。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碧绞。三九已至,卻和暖如春吱窝,著一層夾襖步出監(jiān)牢的瞬間讥邻,已是汗流浹背迫靖。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兴使,地道東北人系宜。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像发魄,于是被迫代替她去往敵國(guó)和親盹牧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容