Android系统启动后Launcher启动(概述)

时间:2021-08-22 16:41:29

Launcher启动流程

1、AMS的systemReady()

上回讲述了《Android系统启动流程》,当系统在Framework层经过一系列多种语言程序有来有回之后,系统服务会被其中,其中包括AMS,startOtherServices()方法执行后阶段,各种被启动起来的Service会各种掉systemReady();其中AMS的systemReady就会被调用,这时候就是告诉应用层说我系统准备好了,SystemServer爸爸要撤了。

SystemServer.java

private void startOtherServices() {
    ...  省略  摘要
     try {
            // TODO: use boot phase
            mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());

            mPackageManagerService.systemReady();
            mDisplayManagerService.systemReady(safeMode, mOnlyCore);
    } catch (Throwable e) {
    }
    mActivityManagerService.systemReady(new Runnable()){
        ...
    }
    wm.systemReady();
    ...

}

1.ActiviyManagerService -> systemReady()

public void systemReady(final Runnable goingCallback) {
            。。。
            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                if (mWaitingUpdate) {
                    return;
                }
                //除非已升级,如果检测没有做过升级,则启动升级
                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
                    public void run() {
                        synchronized (ActivityManagerService.this) {
                            mDidUpdate = true;
                        }
                        showBootMessage(mContext.getText(
                                R.string.android_upgrading_complete),
                                false);
                        writeLastDonePreBootReceivers(doneReceivers);
                        systemReady(goingCallback);
                    }
                }, doneReceivers, UserHandle.USER_OWNER);

                if (mWaitingUpdate) {
                    return;
                }
                mDidUpdate = true;
            }

            mAppOpsService.systemReady();
            mSystemReady = true;
        }

        retrieveSettings();
        loadResourcesOnSystemReady();

        synchronized (this) {
            readGrantedUriPermissionsLocked();
        }


            // Start up initial activity.
            mBooting = true;
            //Launcher启动
            startHomeActivityLocked(mCurrentUserId, "systemReady");

            mStackSupervisor.resumeTopActivitiesLocked();
            //切换其他程序退到后台
            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
        }
    }

可以看到在AMS systemReady()里接着启动了HomeActivity,这时候将要第一个先把Launcher的主程序唤起来。

2.ActiviyManagerService -> startHomeActivityLocked()

boolean startHomeActivityLocked(int userId, String reason) {

        /** 1.创建一个到达Home的Intent action:android.intent.action.MAIN category:android.intent.category.HOME */
        Intent intent = getHomeIntent();

        //2.resolveActivityInfo查找出对应的activityinfo
        ActivityInfo aInfo =
            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
            intent.setComponent(new ComponentName(
                    aInfo.applicationInfo.packageName, aInfo.name));
            // Don't do this if the home app is currently being
            // instrumented.
            aInfo = new ActivityInfo(aInfo);
            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                    aInfo.applicationInfo.uid, true);
            if (app == null || app.instrumentationClass == null) {
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                //3.启动Activity
                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
            }
        }

        return true;
    }

里面1、3步不用介绍了,就是创建Intent和启动Activity的流程,具体来看看
resolveActivityInfo()怎么查找到对应的ActivityInfo的

2.ActiviyManagerService -> resolveActivityInfo()

private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
        ActivityInfo ai = null;
        ComponentName comp = intent.getComponent();
        try {
            if (comp != null) {
                // Factory test.
                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
            } else {

                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
                        intent,
                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                        flags, userId);

                if (info != null) {
                    ai = info.activityInfo;
                }
            }
        } catch (RemoteException e) {
            // ignore
        }

        return ai;
    }

可以看到,从AppGlobals里请出我们熟悉的PackageManager出来搞事了

//1获取IPackageManager接口来查找intent
AppGlobals.getPackageManager().resolveIntent()
//2.第一步实际是跟ActivityThread获取的,而源头是跟ServiceManager获取的,实现类是ApplicationPackageManager
ActivityThread.getPackageManager()  

接下来是弄明白ApplicationPackageManager和PackageManagerService的关系,这是只用一句话是通过IPackageManager接口来进行Binder通讯。具体的实现业务是在PackageManagerService,这里因为Binder的panda先不扩展细节了。

PackageManagerService -> resolveIntent()

@Override
    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
            int flags, int userId) {
        if (!sUserManager.exists(userId)) return null;
        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
        return chooseBestActivity(intent, resolvedType, flags, query, userId);
    }

到这里,ActivityInfo的源头就找到了。流程大致为AMS创建Intent,PMS帮忙查找到ActivityInfo,然后ActivityStack拿着ActivityInfo金钥匙准备启动HomeActivity桌面

2、AMS启动Launcher

mStackSupervisor.startHomeActivity(intent, aInfo, reason);

这里做了三件事:

    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
        //1、将Home任务排到栈顶
        moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
        //2、启动Activity
        startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
                null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
                null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
                null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
                0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
                false /* componentSpecified */,
                null /* outActivity */, null /* container */,  null /* inTask */);
        if (inResumeTopActivity) {
            // 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.
            //3.刚好如果已在Home了,那就直接前置
            scheduleResumeTopActivities();
        }
    }

总结一下:

1、SystemServer启动完所有Boot服务,Core服务、Other服务,就通知所有服务systemReady();

2、其中在AMS的systemReady()里就做了启动Launcher。

3、启动Launcher做了三步:创建Intent;让PMS帮忙通过Binder通讯查找ActivityInfo;让ActivityStack启动Activity。

(后续分享
1.系统级Binder机制的构建过程和在系统中的作用。2.context.startActivity()干了哪些事情)