Launcher进程启动流程

本文详细解析了Android系统中Launcher进程的启动过程,从ActivityTaskManagerService开始,经过启动HomeActivity,到处理Activity启动流程,深入探讨了如何通过Zygote进程fork子进程,并在新进程中运行ActivityThread,直至Activity的真正启动。涉及到的关键步骤包括ActivityStackSupervisor的调度,跨进程通信以及ActivityThread的main方法等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Launcher进程启动流程

在分析ActivityManagerService启动流程的时候说过,ActivityManagerService启动完成后,会调用ActivityTaskManagerService启动HomeActivity并启动Launcher进程

    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");

    mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
  • ActivityTaskManagerService.LocalService -> startHomeOnAllDisplays(currentUserId, “systemReady”)
    @Override
    public boolean startHomeOnAllDisplays(int userId, String reason) {
        synchronized (mGlobalLock) {
            return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
        }
    }
  • RootActivityContainer -> startHomeOnAllDisplays
    boolean startHomeOnAllDisplays(int userId, String reason) {
   
        boolean homeStarted = false;
        for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
   
            final int displayId = mActivityDisplays.get(i).mDisplayId;
            homeStarted |= startHomeOnDisplay(userId, reason, displayId);
        }
        return homeStarted;
    }

根据注释mActivityDisplays是一个List,包含多个Activity,按照Z轴排序,最后一个entry表示显示在最上面的Activity。

  • RootActivityContainer ->startHomeOnDisplay()
    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
            boolean fromHomeKey) {
   
        // Fallback to top focused display if the displayId is invalid.
        if (displayId == INVALID_DISPLAY) {
   
            displayId = getTopDisplayFocusedStack().mDisplayId;
        }

        Intent homeIntent = null;
        ActivityInfo aInfo = null;
        if (displayId == DEFAULT_DISPLAY) {
   
            homeIntent = mService.getHomeIntent();
            aInfo = resolveHomeActivity(userId, homeIntent);
        } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
   
            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
            aInfo = info.first;
            homeIntent = info.second;
        }
        if (aInfo == null || homeIntent == null) {
   
            return false;
        }

        if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
   
            return false;
        }

        // Updates the home component of the intent.
        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
        // Updates the extra information of the intent.
        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;
        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
                displayId);
        return true;
    }

在上面的方法中,通过ActivityTaskManagerService获取HomeIntent,即intent中category为android.intent.category.HOME的Activity。代码中可以看到是以FLAG_ACTIVITY_NEW_TASK方式启动。

  • ActivityStartController -> startHomeActivity
    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
   
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        if (!ActivityRecord.isResolverActivity(aInfo.name)) {
   
            // The resolver activity shouldn't be put in home stack because when the foreground is
            // standard type activity, the resolver activity should be put on the top of current
            // foreground instead of bring home stack to front.
            options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
        }
        options.setLaunchDisplayId(displayId);
        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();
        }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值