欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android10 App 啟動分析進(jìn)程創(chuàng)建源碼解析

 更新時間:2022年10月10日 15:30:51   作者:格子里的夢  
這篇文章主要為大家介紹了Android10 App啟動分析進(jìn)程創(chuàng)建源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

從前文# Android 10 啟動分析之SystemServer篇 (四)中可以得知,系統(tǒng)在完成所有的初始化工作后,會通過

mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");

這條語句,來啟動android系統(tǒng)的第一個App,即Launcher應(yīng)用。這篇文章,我們便以Launcher為引子來探討一下App的啟動流程,在啟動App時,系統(tǒng)究竟做了哪些操作?

AMS調(diào)用startHomeOnAllDisplays方法后,經(jīng)過層層追溯,我們最終將目光定位到RootActivityContainer中的startHomeOnDisplay方法。

RootActivityContainer

RootActivityContainer源碼路徑為 /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java,其相關(guān)代碼如下:

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
         boolean fromHomeKey) {
     // 如果displayId無效,則退回到頂層擁有焦點的顯示設(shè)備
     if (displayId == INVALID_DISPLAY) {
         displayId = getTopDisplayFocusedStack().mDisplayId;
     }
     Intent homeIntent = null;
     ActivityInfo aInfo = null;
     if (displayId == DEFAULT_DISPLAY) {
         //獲取lancher的第一個頁面的intent,其category為Intent.CATEGORY_HOME
         homeIntent = mService.getHomeIntent();
         //通過intent找到launcher中AndroidManifest對應(yīng)的activity標(biāo)簽,解析出相應(yīng)的ActivityInfo和applicationInfo信息
         aInfo = resolveHomeActivity(userId, homeIntent);
     } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
         //多屏顯示功能,具體參考https://source.android.google.cn/devices/tech/display/multi_display/system-decorations#launcher,在此不做分析
         Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
         aInfo = info.first;
         homeIntent = info.second;
     }
     if (aInfo == null || homeIntent == null) {
         return false;
     }
     //在啟動前,校驗是否滿足啟動條件,大概校驗了 displayId的有效性、對應(yīng)activity的啟動模式、是否處于工廠測試模式等等
     if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
         return false;
     }
     // 更新component信息
     homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
     homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
     // 傳入的fromHomeKey的值為false
     if (fromHomeKey) {
         homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
     }
     // Update the reason for ANR debugging to verify if the user activity is the one that
     // actually launched.
     final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
             aInfo.applicationInfo.uid) + ":" + displayId;
       //轉(zhuǎn)到ActivityStartController類中繼續(xù)調(diào)用startHomeActivity方法
     mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
             displayId);
     return true;
 }

我們繼續(xù)往下追蹤:

ActivityStartController

ActivityStartController的源碼路徑為 /frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

相關(guān)代碼如下:

  void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
      //這句話只是創(chuàng)建了一個ActivityOptions的對象
        final ActivityOptions options = ActivityOptions.makeBasic();
        //FULLSCREEN模式啟動Activity
        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        if (!ActivityRecord.isResolverActivity(aInfo.name)) {
            // 判斷當(dāng)前是否擁有多個launcher并處于選擇launcher狀態(tài),否的話設(shè)置ACTIVITY_TYPE_HOME屬性,直接啟動launcher的activity
            options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
        }
        options.setLaunchDisplayId(displayId);
        //執(zhí)行啟動任務(wù)
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
        mLastHomeActivityStartRecord = tmpOutRecord[0];
        final ActivityDisplay display =
                mService.mRootActivityContainer.getActivityDisplay(displayId);
        final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
        if (homeStack != null && homeStack.mInResumeTopActivity) {
            // If we are in resume section already, home activity will be initialized, but not
            // resumed (to avoid recursive resume) and will stay that way until something pokes it
            // again. We need to schedule another resume.
            mSupervisor.scheduleResumeTopActivities();
        }
    }

我們從obtainStarter這行代碼開始看起,這段代碼的執(zhí)行,意味著開始進(jìn)入了activity的啟動流程。

ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
}

這里mFactory是一個Factory接口,其實現(xiàn)類為DefaultFactory 。

 public ActivityStarter obtain() {
            ActivityStarter starter = mStarterPool.acquire();
            if (starter == null) {
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }
            return starter;
        }

調(diào)用obtain方法時,會首先嘗試從緩存池中獲取一個ActivityStarter對象,如果獲取不到,才去新建一個。

我們將目光回轉(zhuǎn),重新聚焦到execute這個方法上。

 int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                        mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            }
        } finally {
            onExecutionComplete();
        }
    }

mayWait為false,進(jìn)入else分支。

  private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
        ...
        //創(chuàng)建被啟動的activity對應(yīng)的ActivityRecord對象
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
        //如果我們啟動的activity與當(dāng)前恢復(fù)的activity的uid不同,請檢查是否允許應(yīng)用程序切換。
        if (voiceSession == null && (stack.getResumedActivity() == null
                || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
                if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
                    mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                            sourceRecord, startFlags, stack, callerApp));
                }
                ActivityOptions.abort(checkedOptions);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }
        mService.onStartActivitySetDidAppSwitch();
        mController.doPendingActivityLaunches(false);
        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
        return res;
    }

在最后,代碼會進(jìn)入如下分支:

   private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
        } finally {
            final ActivityStack currentStack = r.getActivityStack();
            startedActivityStack = currentStack != null ? currentStack : mTargetStack;
            if (ActivityManager.isStartResultSuccessful(result)) {
                if (startedActivityStack != null) {
                    // If there is no state change (e.g. a resumed activity is reparented to
                    // top of another display) to trigger a visibility/configuration checking,
                    // we have to update the configuration for changing to different display.
                    final ActivityRecord currentTop =
                            startedActivityStack.topRunningActivityLocked();
                    if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
                        mRootActivityContainer.ensureVisibilityAndConfig(
                                currentTop, currentTop.getDisplayId(),
                                true /* markFrozenIfConfigChanged */, false /* deferResume */);
                    }
                }
            } else {
                // If we are not able to proceed, disassociate the activity from the task.
                // Leaving an activity in an incomplete state can lead to issues, such as
                // performing operations without a window container.
                final ActivityStack stack = mStartActivity.getActivityStack();
                if (stack != null) {
                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                            null /* intentResultData */, "startActivity", true /* oomAdj */);
                }
                // Stack should also be detached from display and be removed if it's empty.
                if (startedActivityStack != null && startedActivityStack.isAttached()
                        && startedActivityStack.numActivities() == 0
                        && !startedActivityStack.isActivityTypeHome()) {
                    startedActivityStack.remove();
                }
            }
            mService.mWindowManager.continueSurfaceLayout();
        }
        postStartActivityProcessing(r, result, startedActivityStack);
        return result;
    }

調(diào)用startActivityUnchecked方法

其中,調(diào)用了startActivityUnchecked方法。

 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
      ...
        //如果正在啟動的activity與當(dāng)前在頂部的activity相同,那么我們需要檢查它是否應(yīng)該只啟動一次
        final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
        final ActivityRecord topFocused = topStack.getTopActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
                && top.mUserId == mStartActivity.mUserId
                && top.attachedToProcess()
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
                // This allows home activity to automatically launch on secondary display when
                // display added, if home was the top activity on default display, instead of
                // sending new intent to the home activity on default display.
                && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
        if (dontStart) {
            // For paranoia, make sure we have correctly resumed the top activity.
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mRootActivityContainer.resumeFocusedStacksTopActivities();
            }
            ActivityOptions.abort(mOptions);
            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a new activity, and the client said not to do
                // anything if that is the case, so this is it!
                return START_RETURN_INTENT_TO_CALLER;
            }
            deliverNewIntent(top);
            // Don't use mStartActivity.task to show the toast. We're not starting a new activity
            // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
            mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
                    mPreferredDisplayId, topStack);
            return START_DELIVERED_TO_TOP;
        }
        ...
        //往ActivityStack中寫入啟動的activity記錄,同時更新TaskRecord信息
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTaskRecord().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                //如果activity無焦點的,我們不能恢復(fù)它,但仍然希望確保它在啟動時時變得可見(這也將觸發(fā)入場動畫)。此外,我們不希望在當(dāng)前有覆蓋層的Task中恢復(fù)activity,因為正在啟動的activity只需要處于可見的暫停狀態(tài),直到覆蓋層被移除。
                mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
            } else {
                // If the target stack was not previously focusable (previous top running activity
                // on that stack was not visible) then any prior calls to move the stack to the
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable()
                        && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            }
        } else if (mStartActivity != null) {
            mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
        }
        mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
                preferredWindowingMode, mPreferredDisplayId, mTargetStack);
        return START_SUCCESS;
    }

我們關(guān)注一下這行代碼,

 mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);

它調(diào)用了RootActivityContainerresumeFocusedStacksTopActivities方法,啟動目標(biāo)ActivityStack的最頂層activity。

我們接著往下追蹤,它調(diào)用了 ActivityStackresumeTopActivityInnerLocked方法。

 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...
        //暫停上一個activity
        boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
       ...
  // 如果最近的activity沒有歷史記錄,但由于設(shè)備進(jìn)入睡眠狀態(tài)而被停止,而不是停止+銷毀,我們需要確保銷毀它,因為我們正在使一個新的activity處于最頂層。
        if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
                !mLastNoHistoryActivity.finishing) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                    null, "resume-no-history", false);
            mLastNoHistoryActivity = null;
        }
        if (prev != null && prev != next && next.nowVisible) {
            /*下一個activity已經(jīng)可見,所以現(xiàn)在隱藏前一個activity的窗口,以便我們可以盡快顯示新的activity。
            我們只有在前一個結(jié)束時才這樣做,這意味著它在resume的那個之上,所以快速隱藏它是有好處的。
            否則,我們希望按照正常的方式顯示resume的activity,
            這樣我們就可以根據(jù)新activity是否全屏來決定是否應(yīng)該隱藏以前的activity。*/
            if (prev.finishing) {
                prev.setVisibility(false);
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                        "Not waiting for visible to hide: " + prev
                        + ", nowVisible=" + next.nowVisible);
            } else {
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                        "Previous already visible but still waiting to hide: " + prev
                        + ", nowVisible=" + next.nowVisible);
            }
        }
        // Launching this app's activity, make sure the app is no longer
        // considered stopped.
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
        } catch (RemoteException e1) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + next.packageName + ": " + e);
        }
        // 我們正在啟動下一個activity,所以告訴window manager,上一個activity很快就會被隱藏。這樣,它可以知道在計算所需的屏幕方向時忽略它。
        boolean anim = true;
        final DisplayContent dc = getDisplay().mDisplayContent;
        if (prev != null) {
            if (prev.finishing) {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare close transition: prev=" + prev);
                if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    dc.prepareAppTransition(
                            prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_CLOSE
                                    : TRANSIT_TASK_CLOSE, false);
                }
                prev.setVisibility(false);
            } else {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare open transition: prev=" + prev);
                if (mStackSupervisor.mNoAnimActivities.contains(next)) {
                    anim = false;
                    dc.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    dc.prepareAppTransition(
                            prev.getTaskRecord() == next.getTaskRecord() ? TRANSIT_ACTIVITY_OPEN
                                    : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND
                                            : TRANSIT_TASK_OPEN, false);
                }
            }
        } else {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
            if (mStackSupervisor.mNoAnimActivities.contains(next)) {
                anim = false;
                dc.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
            }
        }
        if (anim) {
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }
        mStackSupervisor.mNoAnimActivities.clear();
        if (next.attachedToProcess()) {
            ... 
            //只有啟動過的activity才會進(jìn)入此分支
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    //冷啟動的過渡頁,在這里會載入manifest配置的主題背景,如果沒有的話,默認(rèn)白屏或黑屏
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

通過源碼,我們可以得知:先對上一個Activity執(zhí)行pause操作,再啟動目標(biāo)activity,最終進(jìn)入到了ActivityStackSupervior.startSpecificActivityLocked方法中。在啟動Activity之前,調(diào)用了next.showStartingWindow方法來展示一個window,這就是冷啟動時出現(xiàn)白屏的原因。

我們繼續(xù)往下追蹤:

ActivityStackSupervisor

ActivityStackSupervisor的源碼路徑為 /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

 void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }
        // Suppress transition until the new activity becomes ready, otherwise the keyguard can
        // appear for a short amount of time before the new process with the new activity had the
        // ability to set its showWhenLocked flags.
        if (getKeyguardController().isKeyguardLocked()) {
            r.notifyUnknownVisibilityLaunched();
        }
        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            //發(fā)布消息以啟動進(jìn)程,從而避免在ATMS鎖被持有的情況下調(diào)用AMS時可能出現(xiàn)的死鎖
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

上面這段方法里有個很重要的判斷,if(wpc != null && wpc.hasThread()),通過進(jìn)程名和application uid 獲取的WindowProcessController對象進(jìn)行校驗,判斷要啟動的activity進(jìn)程是否已啟動。顯然,app第一次啟動時,進(jìn)程還不存在,首先先得創(chuàng)建應(yīng)用進(jìn)程。

final Message msg = PooledLambda.obtainMessage(
                 ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                 r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
         mService.mH.sendMessage(msg);

這里通過Handler,發(fā)送了一條Message,以避免在ATMS鎖被持有的情況下調(diào)用AMS時可能出現(xiàn)的死鎖。這條Message實際調(diào)用的是ActivityManagerServicestartProcess方法。

啟動進(jìn)程

ActivityManagerService的源碼位置為 /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

startProcess實際調(diào)用的是startProcessLocked方法,我們直接從它看起。

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

這里調(diào)用的是 ProcessList類里的startProcessLocked的方法,我們繼續(xù)往下看。

  final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        ...
        ProcessRecord app;
        // 以下三種情況,我們不需要做任何額外的處理
        // (1) 存在一個application 記錄
        // (2) 調(diào)用者認(rèn)為它仍然存活,或者沒有線程對象連接到它,所以我們知道它沒有crash
        // (3) 有一個pid分配給它,所以它要么正在啟動,要么已經(jīng)運行
        if (app != null && app.pid > 0) {
            if ((!knownToBeDead && !app.killed) || app.thread == null) {
                // 我們已經(jīng)有應(yīng)用程序在運行,或者正在等待它出現(xiàn)(我們有一個pid,但還沒有它的線程),所以保持它
                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
                // If this is a new package in the process, add the package to the list
                app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
                checkSlow(startTime, "startProcess: done, added package to proc");
                return app;
            }
            // An application record is attached to a previous process,
            // clean it up now.
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
            checkSlow(startTime, "startProcess: bad proc running, killing");
            ProcessList.killProcessGroup(app.uid, app.pid);
            mService.handleAppDiedLocked(app, true, true);
            checkSlow(startTime, "startProcess: done killing old proc");
        }
        if (app == null) {
            checkSlow(startTime, "startProcess: creating new process record");
            //創(chuàng)建一條ProcessRecord
            app = new ProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
            if (app == null) {
                Slog.w(TAG, "Failed making new process record for "
                        + processName + "/" + info.uid + " isolated=" + isolated);
                return null;
            }
            app.crashHandler = crashHandler;
            app.isolatedEntryPoint = entryPoint;
            app.isolatedEntryPointArgs = entryPointArgs;
            checkSlow(startTime, "startProcess: done creating new process record");
        } else {
            // If this is a new package in the process, add the package to the list
            app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
            checkSlow(startTime, "startProcess: added package to existing proc");
        }
        // If the system is not ready yet, then hold off on starting this
        // process until it is.
        if (!mService.mProcessesReady
                && !mService.isAllowedWhileBooting(info)
                && !allowWhileBooting) {
            if (!mService.mProcessesOnHold.contains(app)) {
                mService.mProcessesOnHold.add(app);
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                    "System not ready, putting on hold: " + app);
            checkSlow(startTime, "startProcess: returning with proc on hold");
            return app;
        }
        checkSlow(startTime, "startProcess: stepping in to startProcess");
        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }

可以看到,在啟動一個新的進(jìn)程時,有兩個比較重要的步驟。一是通過newProcessRecordLocked方法首先創(chuàng)建一條進(jìn)程記錄,然后再通過startProcessLocked方法去創(chuàng)建一個進(jìn)程。

 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
            String abiOverride) {
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
               ...
            final String entryPoint = "android.app.ActivityThread";
            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        } catch (RuntimeException e) {
            Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false, app.userId, "start failure");
            return false;
        }
    }

這里請注意一下entryPoint這個變量的值————android.app.ActivityThread,它會經(jīng)過一段漫長的調(diào)用鏈,最終在RuntimeInit這個類中發(fā)揮它的作用。

boolean startProcessLocked(HostingRecord hostingRecord,
            String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        app.pendingStart = true;
        app.killedByAm = false;
        app.removed = false;
        app.killed = false;
       ...
        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
        app.setStartParams(uid, hostingRecord, seInfo, startTime);
        app.setUsingWrapper(invokeWith != null
                || SystemProperties.get("wrap." + app.processName) != null);
        mPendingStarts.put(startSeq, app);
        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        //默認(rèn)以異步方式啟動
            mService.mProcStartHandler.post(() -> {
                try {
                    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                            entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
                            app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
                    synchronized (mService) {
                        handleProcessStartedLocked(app, startResult, startSeq);
                    }
                } catch (RuntimeException e) {
                    synchronized (mService) {
                        Slog.e(ActivityManagerService.TAG, "Failure starting process "
                                + app.processName, e);
                        mPendingStarts.remove(startSeq);
                        app.pendingStart = false;
                        mService.forceStopPackageLocked(app.info.packageName,
                                UserHandle.getAppId(app.uid),
                                false, false, true, false, false, app.userId, "start failure");
                    }
                }
            });
            return true;
        } else {
            try {
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                        invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {
                Slog.e(ActivityManagerService.TAG, "Failure starting process "
                        + app.processName, e);
                app.pendingStart = false;
                mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                        false, false, true, false, false, app.userId, "start failure");
            }
            return app.pid > 0;
        }
    }

繼續(xù)看startProcess方法:

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            final Process.ProcessStartResult startResult;
            //hostingRecord初始化參數(shù)為null,并未指定mHostingZygote屬性,因此會進(jìn)入最后一個分支
            if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*useUsapPool=*/ false,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

Process的源碼位置為 frameworks/base/core/java/android/os/Process.java。

 public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, zygoteArgs);
    }

其中ZYGOTE_PROCESS是一個ZygoteProcess對象,它實際調(diào)用的是ZygoteProcess里的start方法。

public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, @Nullable int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  @Nullable String seInfo,
                                                  @NonNull String abi,
                                                  @Nullable String instructionSet,
                                                  @Nullable String appDataDir,
                                                  @Nullable String invokeWith,
                                                  @Nullable String packageName,
                                                  boolean useUsapPool,
                                                  @Nullable String[] zygoteArgs) {
        // TODO (chriswailes): Is there a better place to check this value?
        if (fetchUsapPoolEnabledPropWithMinInterval()) {
            informZygotesOfUsapPoolStatus();
        }
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, useUsapPool, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }
 private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      @Nullable String seInfo,
                                                      @NonNull String abi,
                                                      @Nullable String instructionSet,
                                                      @Nullable String appDataDir,
                                                      @Nullable String invokeWith,
                                                      boolean startChildZygote,
                                                      @Nullable String packageName,
                                                      boolean useUsapPool,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<>();
        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
            argsForZygote.add("--mount-external-default");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
            argsForZygote.add("--mount-external-full");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
            argsForZygote.add("--mount-external-installer");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
            argsForZygote.add("--mount-external-legacy");
        }
        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
        // --setgroups is a comma-separated list
        if (gids != null && gids.length > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("--setgroups=");
            int sz = gids.length;
            for (int i = 0; i < sz; i++) {
                if (i != 0) {
                    sb.append(',');
                }
                sb.append(gids[i]);
            }
            argsForZygote.add(sb.toString());
        }
        if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }
        if (seInfo != null) {
            argsForZygote.add("--seinfo=" + seInfo);
        }
        if (instructionSet != null) {
            argsForZygote.add("--instruction-set=" + instructionSet);
        }
        if (appDataDir != null) {
            argsForZygote.add("--app-data-dir=" + appDataDir);
        }
        if (invokeWith != null) {
            argsForZygote.add("--invoke-with");
            argsForZygote.add(invokeWith);
        }
        if (startChildZygote) {
            argsForZygote.add("--start-child-zygote");
        }
        if (packageName != null) {
            argsForZygote.add("--package-name=" + packageName);
        }
        argsForZygote.add(processClass);
        if (extraArgs != null) {
            Collections.addAll(argsForZygote, extraArgs);
        }
        synchronized(mLock) {
            // The USAP pool can not be used if the application will not use the systems graphics
            // driver.  If that driver is requested use the Zygote application start path.
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              useUsapPool,
                                              argsForZygote);
        }
    }

值得注意的是上面這段代碼的openZygoteSocketIfNeeded這個方法,它采用socket通信方式,嘗試連接路徑為/dev/socket/、名稱為zygote的服務(wù)端。

zygoteSendArgsAndGetResult方法里實際調(diào)用了attemptZygoteSendArgsAndGetResult方法,內(nèi)容如下:

 private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();
            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();
            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);
        }
    }

請注意上述方法的zygoteWriter這個變量,它負(fù)責(zé)將進(jìn)程啟動參數(shù)發(fā)送給服務(wù)端,由服務(wù)端去孵化進(jìn)程。那么,這個服務(wù)端到底是哪個類呢?

答案是ZygoteServer.java,源碼路徑為 frameworks/base/core/java/com/android/internal/os/ZygoteServer.java.

ZygoteServer會在系統(tǒng)啟動的時候,創(chuàng)建一個Socket服務(wù)端,用于接收客戶端的fork請求。ZygoteServer在初始化結(jié)束后,會調(diào)用runSelectLoop方法,用于處理客戶端的消息。當(dāng)客戶端請求fork進(jìn)程時,runSelectLoop方法會轉(zhuǎn)交給ZygoteConnection類的processOneCommand方法去處理。

(ps : 如需了解更多關(guān)于Zegote的信息,請參考文章 Android 10 啟動分析之Zygote篇

 Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        ZygoteArguments parsedArgs = null;
        FileDescriptor[] descriptors;
       ...
        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.mTargetSdkVersion);
        try {
            if (pid == 0) {
                // in child
                zygoteServer.setForkChild();
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;
                return handleChildProc(parsedArgs, descriptors, childPipeFd,
                        parsedArgs.mStartChildZygote);
            } else {
                // In the parent. A pid < 0 indicates a failure and will be handled in
                // handleParentProc.
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                handleParentProc(pid, descriptors, serverPipeFd);
                return null;
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }
 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            int targetSdkVersion) {
        ZygoteHooks.preFork();
        // Resets nice priority for zygote process.
        resetNicePriority();
        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir);
        // Enable tracing as soon as possible for the child process.
        if (pid == 0) {
            Zygote.disableExecuteOnly(targetSdkVersion);
            Trace.setTracingEnabled(true, runtimeFlags);
            // Note that this event ends at the end of handleChildProc,
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
        }
        ZygoteHooks.postForkCommon();
        return pid;
    }

上述Zygote類在這個過程中主要做了以下幾點工作:

  • 調(diào)用dalvik中ZygoteHookspreFrok進(jìn)行預(yù)處理,主要是停止4個Daemon子線程,HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon,等待所有的子線程結(jié)束,最后完成gc堆的初始化工作。
  • 調(diào)用com_android_internal_os_zygote.cpp中的nativeForkAndSpecialize方法,主要工作是通過linux機(jī)制fork一個子進(jìn)程,以及進(jìn)程的一些資源處理,selinux權(quán)限處理,JAVA堆線程的一些處理。
  • 調(diào)用ZygoteHookspostForkCommon方法,啟動Zygote的4個Daemon線程。

在執(zhí)行forkAndSpecialize方法后,代碼將繼續(xù)執(zhí)行ZygoteConnection中的handleChildProc這個方法。

private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
           FileDescriptor pipeFd, boolean isZygote) {
      ...
       if (parsedArgs.mInvokeWith != null) {
           WrapperInit.execApplication(parsedArgs.mInvokeWith,
                   parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                   VMRuntime.getCurrentInstructionSet(),
                   pipeFd, parsedArgs.mRemainingArgs);
           // Should not get here.
           throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
       } else {
           if (!isZygote) {
           //進(jìn)入此分支
               return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                       parsedArgs.mRemainingArgs, null /* classLoader */);
           } else {
               return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                       parsedArgs.mRemainingArgs, null /* classLoader */);
           }
       }
   }
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
         ...
         //初始化運行環(huán)境
        RuntimeInit.commonInit();
        //啟動binder線程池
        ZygoteInit.nativeZygoteInit();
        //程序入口函數(shù)
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

RuntimeInit.applicationInit這個方法

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);
        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        final Arguments args = new Arguments(argv);
        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
 protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;
        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }
        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        return new MethodAndArgsCaller(m, argv);
    }

這里通過反射獲得了className變量中的main方法,并傳遞給MethodAndArgsCaller用于構(gòu)造一個Runnable。只要執(zhí)行此Runnable,就會開始執(zhí)行className變量中的main方法。

className變量的值究竟是什么呢?

還記得我們前文重點強(qiáng)調(diào)的entryPoint這個變量嗎?不記得的讀者請自行返回再查看一下。android.app.ActivityThread就是我們要執(zhí)行的目標(biāo)類。

ActivityThread類main方法的調(diào)用,標(biāo)識著 應(yīng)用已全部完成進(jìn)程的創(chuàng)建和初始化過程,下面將進(jìn)入ApplicationActivity的創(chuàng)建與啟動流程。下一篇文章,我們再來繼續(xù)探討剩下的內(nèi)容。

最后,讓我們用圖表對上述流程做一個總結(jié)歸納:

[ActivityManagerService.java]
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
   |
[RootActivityContainer.java]
startHomeOnDisplay()		     //獲取lancher的第一個頁面的intent,其category為Intent.CATEGORY_HOME
   |
[ActivityStartController.java]
startHomeActivity()
   |
[ActivityStarter.java]
execute()			     //開始進(jìn)入activity啟動流程	
startActivity()
startActivityUnchecked()
   |
[RootActivityContainer.java]
resumeFocusedStacksTopActivities()   //啟動目標(biāo)ActivityStack的最頂層activity
   |
[ActivityStack.java]
resumeTopActivityInnerLocked()      //暫停上一個activity,載入manifest的主題背景
   |
[ActivityStackSupervisor.java]
startSpecificActivityLocked()       //檢查進(jìn)程是否已啟動,通過handler消息機(jī)制啟動新的進(jìn)程
   |
[ActivityManagerService.java]
startProcessLocked()
   |
[ProcessList.java]
startProcessLocked()               //指定了進(jìn)程創(chuàng)建成功后程序啟動入口類為android.app.ActivityThread
startProcess()
   |
[Process.java]
start()
   |
[ZygoteProcess.java]
start()
startViaZygote()		   //初始化Zygote的啟動參數(shù),連接ZygoteServer服務(wù)端
attemptZygoteSendArgsAndGetResult()
   |
[ZygoteServer.java]
processOneCommand()
   |		|
   |  [Zygote.java]
   |  forkAndSpecialize()
   |        |
   |  [ZygoteHooks.java]
   |	  preFrok()		   //停止4個子線程,等待所有的子線程結(jié)束,最后完成gc堆的初始化工作
   |		|
   |  [com_android_internal_os_zygote.cpp]	
   |  nativeForkAndSpecialize()       //fork子進(jìn)程
   |        |
   |  [ZygoteHooks.java]
   |  postForkCommon()                //啟動Zygote的4個Daemon線程
   |
[ZygoteConnection.java]
handleChildProc()
   |
[ZygoteInit.java]
zygoteInit()				//初始化運行環(huán)境、啟動binder線程池
   |
[RuntimeInit.java]
applicationInit()
   |
[ActivityThread.java]
main()

以上就是Android10 App 啟動分析進(jìn)程創(chuàng)建源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Android10 App啟動進(jìn)程創(chuàng)建的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論