深入浅出Android底层(十一)-Android系统启动过程--SystemServer到Home的启动

849 阅读9分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

前言

上篇文章我们提到了Launcher进程,我们探究到了从Launcher桌面的icon点击到startActivity中间到底发生了什么,Launcher进程本身也是一个App,那么Android是如何启动我们的桌面应用的,了解了这个,我们就可以大致了解Launcher进程是如何通过进程间通信启动别的app了.

一、Zygote

通过前几篇文章的分析,我们已经大致知道init进程首先启动了Zygote进程,Zygote承担着孵化进程的任务,它第一个孵化的进程就是SystemeServer进程.SystemServer进程,SystemServer进程又启动了AMS,WMS,PWS,InputManager等主要的辅助服务.

二、SystemServer

2.1 main()

public final class SystemServer {


    public static void main(String[] args) {
        new SystemServer().run();
    }
    

    public SystemServer() {
        // Check for factory test mode.
        mFactoryTestMode = FactoryTest.getMode();
        // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
        mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
    }

    
}

这个主函数做了初始化的设置,设置了是否从boot开机之后的标识位.

2.2 run()

    private void run() {
            //1.记录好native上来的虚拟机参数
            ...
            Looper.prepareMainLooper();

            // Initialize native services.
            //初始化的android_servers.so包里面包含了大量的native的android服务
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

        // Start services.
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

run方法里主要做了四件事.

  • 1、记录从zygote过来的虚拟机等runtime参数,初始化android_server的so库,android_server初始化了重要的系统服务的native层.
  • 2、为SystemServer设置Looper,并进入到loop的循环,等待其他应用的调用.
  • 3、初始化SystemServer的context以及初始化SystemServiceManager
  • 4、启动各大主要的系统服务.

2.3 createSystemContext

在初始化SystemServer之前,调用了systemMain()方法初始化了ActivityThread

同时为系统设置了默认主题

    private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

2.4 SystemServiceManager

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
  • 1、SystemServiceManager作为所有Android服务的启动者和控制者,启动后被加入到了LocalServices中
  • 2、LocalServices的作用,实际上和SystemServiceManager的作用很相似,LocalService的内部有一个ArrayMap,直接保存着对应服务的实例

而SystemServiceManager往往通过反射,直接调用Context参数的构造函数.

三、 启动各大服务


        // Start services.
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

可以看到,在声明了SystemServiceManager之后,调用了很多启用服务的方法.

3.1 startBootstrapServices

   private void startBootstrapServices() {
        // Wait for installd to finish starting up so that it has a chance to
        // create critical directories such as /data/user with the appropriate
        // permissions.  We need this to complete before we initialize other services.
        Installer installer = mSystemServiceManager.startService(Installer.class);

        // Activity manager runs the show.
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        // Power manager needs to be started early because other services need it.
        // Native daemons may be watching for it to be registered so it must be ready
        // to handle incoming binder calls immediately (including being able to verify
        // the permissions for those calls).
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

        // Now that the power manager has been started, let the activity manager
        // initialize power management features.
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
        mActivityManagerService.initPowerManagement();
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

        // Manages LEDs and display backlight so we need it to bring up the display.
        mSystemServiceManager.startService(LightsService.class);

        // Display manager is needed to provide display metrics before package manager
        // starts up.
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

        // We need the default display before we can initialize the package manager.
        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

        // Only run "core" apps if we're encrypting the device.
        String cryptState = SystemProperties.get("vold.decrypt");
        if (ENCRYPTING_STATE.equals(cryptState)) {
            Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
            mOnlyCore = true;
        } else if (ENCRYPTED_STATE.equals(cryptState)) {
            Slog.w(TAG, "Device encrypted - only parsing core apps");
            mOnlyCore = true;
        }

        // Start the package manager.
        traceBeginAndSlog("StartPackageManagerService");
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

        // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
        // A/B artifacts after boot, before anything else might touch/need them.
        // Note: this isn't needed during decryption (we don't have /data anyways).
        if (!mOnlyCore) {
            boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                    false);
            if (!disableOtaDexopt) {
                traceBeginAndSlog("StartOtaDexOptService");
                try {
                    OtaDexoptService.main(mSystemContext, mPackageManagerService);
                } catch (Throwable e) {
                    reportWtf("starting OtaDexOptService", e);
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                }
            }
        }

        traceBeginAndSlog("StartUserManagerService");
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

        // Initialize attribute cache used to cache resources from packages.
        AttributeCache.init(mSystemContext);

        // Set up the Application instance for the system process and get started.
        mActivityManagerService.setSystemProcess();

        // The sensor service needs access to package manager service, app ops
        // service, and permissions service, therefore we start it after them.
        startSensorService();
    }
  • 1、Install在SystemServer端,等待installd的服务通过Binder连接进来。接着这个installd会通过installd.rc读取脚本,生成一个installd的进程,该进程的作用是用来安装软件用的
  • 2、ActivityManagerService就是我们最熟悉的AMS了,贯穿整个App应用的服务,负责的主要功能就是管理启动的Activity,同时把install这个服务装载进去.
  • 3、PowerManagerService是负责协助管理电源的服务.
  • 4、LightService控制手机的灯的设备
  • 5、DisplayManagerService从4.2开始作为手机管理显示的服务.
  • 6、PackageManagerService管理app应用的package的信息.
  • 7、UserManagerService,早期Android是一个单用户系统,当Android成为了多用户系统,而多用户就是通过这个类去管理
  • 8、SensorService,传感器的初始化.

3.2 startCoreServices


    /**
     * Starts some essential services that are not tangled up in the bootstrap process.
     */
    private void startCoreServices() {
        // Tracks the battery level.  Requires LightService.
        mSystemServiceManager.startService(BatteryService.class);

        // Tracks application usage stats.
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));

        // Tracks whether the updatable WebView is in a ready state and watches for update installs.
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }
  • 1.启动了BatteryService,主要用于监控电池,电量信息的服务
  • 2、UsageStatsManagerInternal监控应用服务,常用的应用如检测应用使用时间等.
  • 3、如果打开了webview标识位,则启动webview的更新服务

3.3 startOtherServices

    private void startOtherServices() {
    ...
        try {
            wm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

        if (safeMode) {
            mActivityManagerService.showSafeModeOverlay();
        }

        // Update the configuration for this context by hand, because we're going
        // to start using it before the config change done in wm.systemReady() will
        // propagate to it.
        Configuration config = wm.computeNewConfiguration();
        DisplayMetrics metrics = new DisplayMetrics();

        ...
        

  // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        mActivityManagerService.systemReady(new Runnable() {

}
}

在这里初始化了许多其他服务,如Inputmanager,network等等,剩下系统的调用服务都将会在这里实现.

四、AMS

   public void systemReady(final Runnable goingCallback) {
        ...
        
       
       //添加进程列表
        ArrayList<ProcessRecord> procsToKill = null;
        synchronized(mPidsSelfLocked) {
            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (!isAllowedWhileBooting(proc.info)){
                    if (procsToKill == null) {
                        procsToKill = new ArrayList<ProcessRecord>();
                    }
                    procsToKill.add(proc);
                }
            }
        }

            startHomeActivityLocked(currentUserId, "systemReady");

           ....
    }

SystemeServer在startOtherServices中调用了AMS的systemReady方法,并且塞入了一个callback

而在AMS的systemReady方法中将当前的进程配置到AMS进程列表中,初始化了PMS,为后续启动Home界面读取Launcher目录下的界面App做准备,最后获取UserController获取当前用户id,使用startHomeActivityLocked开始创建Home界面

4.1 startHomeActivityLocked

    boolean startHomeActivityLocked(int userId, String reason) {
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            // We are running in factory test mode, but unable to find
            // the factory test app, so just sit around displaying the
            // error message and don't try to start anything.
            return false;
        }
        Intent intent = getHomeIntent();
        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);
                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
            }
        } else {
            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
        }

        return true;
    }
4.1.1 getHomeIntent
    Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

第一步,通过getHomeIntent()创建一个有效的intent,并且获取对应的ActivityInfo

而这个getHomeIntent会给其添加一个Intent.CATEGORY_HOME的标识位

4.1.2 resolveActivityInfo

resolveActivityInfo()方法通过Binder跨进程通知PMS从系统已安装的应用中,找到一个符合HomeIntent的Activity.

   private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
        ActivityInfo ai = null;
        //系统正常启动时,component为null
        ComponentName comp = intent.getComponent();
        try {
            if (comp != null) {
                // Factory test.
                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
            } else {
            
            
            //resolveIntent做了两件事
            //1.通过queryIntentActivities来查找符合HomeIntent需求的Activities
            //2.通过chooseBaseActivity找到最符合Intent需求的Activity信息
                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
                        intent,
                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                        flags, userId);

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

        return ai;
    }

/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java


    @Override
    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
            int flags, int userId) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");

            if (!sUserManager.exists(userId)) return null;
            flags = updateFlagsForResolve(flags, userId, intent);
            enforceCrossUserPermission(Binder.getCallingUid(), userId,
                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");

            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
                    flags, userId);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            final ResolveInfo bestChoice =
                    chooseBestActivity(intent, resolvedType, flags, query, userId);
            return bestChoice;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

4.2 startHomeActivityLocked

  mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
    void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
        mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
        startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/,
                null /*resolvedType*/, aInfo, null /*rInfo*/, 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 (mSupervisor.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.
            mSupervisor.scheduleResumeTopActivities();
        }
    }

关键方法是 moveHomeStackTaskToTop以及scheduleResumeTopActivities

4.3 moveHomeStackTaskToTop

   void moveHomeStackTaskToTop(int homeStackTaskType) {
        final int top = mTaskHistory.size() - 1;
        for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.taskType == homeStackTaskType) {
                if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
                        "moveHomeStackTaskToTop: moving " + task);
                mTaskHistory.remove(taskNdx);
                mTaskHistory.add(top, task);
                updateTaskMovement(task, true);
                return;
            }
        }
    }

先从TaskHistory任务栈中取出顶部Activity,如果此时Activity栈有Activity的存在,则把Home的Activity更新到顶部

4.4 scheduleResumeTopActivities

    final void scheduleResumeTopActivities() {
        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
        }
    }

此时由AMS内部的handler接收消息

                case RESUME_TOP_ACTIVITY_MSG: {
                    synchronized (mService) {
                        resumeFocusedStackTopActivityLocked();
                    }
                } break;

这个handler就是在SystemServer生成的looper传进来,其中RESUME_TOP_ACTIVITY_MSG的分支将会调用resumeFocusedStackTopActivityLocked

4.5 resumeFocusedStackTopActivityLocked

    boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
    }

此时将会判断到,当前栈对应的ActivityRecord是否存在,此时是第一次打开的,所以此时ActivityRecord还没有生成,将会走到resumeTopActivityUncheckedLocked

4.6 resumeTopActivityUncheckedLocked

   boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
  private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");

        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }
        ...
        
      } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null, true);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

此时由于必定不存在Activity,此时必定通过ActivityStackSupervisor启动startSpecificActivityLocked


    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, 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.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

4.7 startProcessLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
                null /* entryPoint */, null /* entryPointArgs */);
    }

    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        long startTime = SystemClock.elapsedRealtime();
        
        ...
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
....

在这里通过Process.start创建了新的进程,新的进程又会导入ActivityThread类,并执行它的main函数

这一阶段主要检查activity所在的进程是否存在,如果存在,就直接通知这个进程,在该进程中启动这个Activity,不存在的话,会调用Process.start创建一个新进程(执行在AMS进程)

至此我们的Launcher进程就被创建,接下来就是创建ActivityThread和 ApplicationThread了