亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

正文

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

mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");

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

AMS調(diào)用startHomeOnAllDisplays方法后,經(jīng)過(guò)層層追溯,我們最終將目光定位到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無(wú)效,則退回到頂層擁有焦點(diǎn)的顯示設(shè)備
     if (displayId == INVALID_DISPLAY) {
         displayId = getTopDisplayFocusedStack().mDisplayId;
     }
     Intent homeIntent = null;
     ActivityInfo aInfo = null;
     if (displayId == DEFAULT_DISPLAY) {
         //獲取lancher的第一個(gè)頁(yè)面的intent,其category為Intent.CATEGORY_HOME
         homeIntent = mService.getHomeIntent();
         //通過(guò)intent找到launcher中AndroidManifest對(duì)應(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;
     }
     //在啟動(dòng)前,校驗(yàn)是否滿足啟動(dòng)條件,大概校驗(yàn)了 displayId的有效性、對(duì)應(yīng)activity的啟動(dòng)模式、是否處于工廠測(cè)試模式等等
     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)建了一個(gè)ActivityOptions的對(duì)象
        final ActivityOptions options = ActivityOptions.makeBasic();
        //FULLSCREEN模式啟動(dòng)Activity
        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        if (!ActivityRecord.isResolverActivity(aInfo.name)) {
            // 判斷當(dāng)前是否擁有多個(gè)launcher并處于選擇launcher狀態(tài),否的話設(shè)置ACTIVITY_TYPE_HOME屬性,直接啟動(dòng)launcher的activity
            options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
        }
        options.setLaunchDisplayId(displayId);
        //執(zhí)行啟動(dòng)任務(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這行代碼開(kāi)始看起,這段代碼的執(zhí)行,意味著開(kāi)始進(jìn)入了activity的啟動(dòng)流程。

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

這里mFactory是一個(gè)Factory接口,其實(shí)現(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方法時(shí),會(huì)首先嘗試從緩存池中獲取一個(gè)ActivityStarter對(duì)象,如果獲取不到,才去新建一個(gè)。

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

 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)建被啟動(dòng)的activity對(duì)應(yīng)的ActivityRecord對(duì)象
        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();
        //如果我們啟動(dòng)的activity與當(dāng)前恢復(fù)的activity的uid不同,請(qǐng)檢查是否允許應(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;
    }

在最后,代碼會(huì)進(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) {
      ...
        //如果正在啟動(dòng)的activity與當(dāng)前在頂部的activity相同,那么我們需要檢查它是否應(yīng)該只啟動(dò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中寫入啟動(dòng)的activity記錄,同時(shí)更新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無(wú)焦點(diǎn)的,我們不能恢復(fù)它,但仍然希望確保它在啟動(dòng)時(shí)時(shí)變得可見(jiàn)(這也將觸發(fā)入場(chǎng)動(dòng)畫)。此外,我們不希望在當(dāng)前有覆蓋層的Task中恢復(fù)activity,因?yàn)檎趩?dòng)的activity只需要處于可見(jiàn)的暫停狀態(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方法,啟動(dòng)目標(biāo)ActivityStack的最頂層activity。

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

 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...
        //暫停上一個(gè)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沒(méi)有歷史記錄,但由于設(shè)備進(jìn)入睡眠狀態(tài)而被停止,而不是停止+銷毀,我們需要確保銷毀它,因?yàn)槲覀冋谑挂粋€(gè)新的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) {
            /*下一個(gè)activity已經(jīng)可見(jiàn),所以現(xiàn)在隱藏前一個(gè)activity的窗口,以便我們可以盡快顯示新的activity。
            我們只有在前一個(gè)結(jié)束時(shí)才這樣做,這意味著它在resume的那個(gè)之上,所以快速隱藏它是有好處的。
            否則,我們希望按照正常的方式顯示resume的activity,
            這樣我們就可以根據(jù)新activity是否全屏來(lái)決定是否應(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);
        }
        // 我們正在啟動(dòng)下一個(gè)activity,所以告訴window manager,上一個(gè)activity很快就會(huì)被隱藏。這樣,它可以知道在計(jì)算所需的屏幕方向時(shí)忽略它。
        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()) {
            ... 
            //只有啟動(dòng)過(guò)的activity才會(huì)進(jìn)入此分支
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    //冷啟動(dòng)的過(guò)渡頁(yè),在這里會(huì)載入manifest配置的主題背景,如果沒(méi)有的話,默認(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;
    }

通過(guò)源碼,我們可以得知:先對(duì)上一個(gè)Activity執(zhí)行pause操作,再啟動(dòng)目標(biāo)activity,最終進(jìn)入到了ActivityStackSupervior.startSpecificActivityLocked方法中。在啟動(dòng)Activity之前,調(diào)用了next.showStartingWindow方法來(lái)展示一個(gè)window,這就是冷啟動(dòng)時(shí)出現(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ā)布消息以啟動(dòng)進(jìn)程,從而避免在ATMS鎖被持有的情況下調(diào)用AMS時(shí)可能出現(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);
        }
    }

上面這段方法里有個(gè)很重要的判斷,if(wpc != null && wpc.hasThread()),通過(guò)進(jìn)程名和application uid 獲取的WindowProcessController對(duì)象進(jìn)行校驗(yàn),判斷要啟動(dòng)的activity進(jìn)程是否已啟動(dòng)。顯然,app第一次啟動(dòng)時(shí),進(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);

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

啟動(dòng)進(jìn)程

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

startProcess實(shí)際調(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) 存在一個(gè)application 記錄
        // (2) 調(diào)用者認(rèn)為它仍然存活,或者沒(méi)有線程對(duì)象連接到它,所以我們知道它沒(méi)有crash
        // (3) 有一個(gè)pid分配給它,所以它要么正在啟動(dòng),要么已經(jīng)運(yùn)行
        if (app != null && app.pid > 0) {
            if ((!knownToBeDead && !app.killed) || app.thread == null) {
                // 我們已經(jīng)有應(yīng)用程序在運(yùn)行,或者正在等待它出現(xiàn)(我們有一個(gè)pid,但還沒(méi)有它的線程),所以保持它
                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;
    }

可以看到,在啟動(dòng)一個(gè)新的進(jìn)程時(shí),有兩個(gè)比較重要的步驟。一是通過(guò)newProcessRecordLocked方法首先創(chuàng)建一條進(jìn)程記錄,然后再通過(guò)startProcessLocked方法去創(chuàng)建一個(gè)進(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;
        }
    }

這里請(qǐng)注意一下entryPoint這個(gè)變量的值————android.app.ActivityThread,它會(huì)經(jīng)過(guò)一段漫長(zhǎng)的調(diào)用鏈,最終在RuntimeInit這個(gè)類中發(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)以異步方式啟動(dòng)
            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屬性,因此會(huì)進(jìn)入最后一個(gè)分支
            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是一個(gè)ZygoteProcess對(duì)象,它實(shí)際調(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這個(gè)方法,它采用socket通信方式,嘗試連接路徑為/dev/socket/、名稱為zygote的服務(wù)端。

zygoteSendArgsAndGetResult方法里實(shí)際調(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);
        }
    }

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

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

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

(ps : 如需了解更多關(guān)于Zegote的信息,請(qǐng)參考文章 Android 10 啟動(dòng)分析之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類在這個(gè)過(guò)程中主要做了以下幾點(diǎn)工作:

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

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

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) {
         ...
         //初始化運(yùn)行環(huán)境
        RuntimeInit.commonInit();
        //啟動(dòng)binder線程池
        ZygoteInit.nativeZygoteInit();
        //程序入口函數(shù)
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

RuntimeInit.applicationInit這個(gè)方法

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);
    }

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

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

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

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

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

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

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

相關(guān)文章

最新評(píng)論