Android 系统启动流程(二)

1. 前言

在 Android 系统启动流程(一)中,描述了 Android 系统启动流程中从按下 Power 到 Zygote 进程的启动。最终 Zygote 启动了 SystemServer,并调用了 SystemServer 中的 main 方法,这里继续分析启动 SystemServer 后的流程。

2. SystemServer 源码

SystemServer 的入口为 main 方法:

    /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }

创建了一个它本身的实例,并且调用了 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"));

        mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
        mRuntimeStartUptime = SystemClock.uptimeMillis();
    }

run 方法:

    private void run() {
        try {
             
            ...
            ...
            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

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

        ...
        ...

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

在 run 方法中,主要创建 SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理,后续对于系统服务的启动都依赖它。紧接着就是创建一堆的 Service:

            startBootstrapServices();
            startCoreServices();
            startOtherServices();

主要分为三类:引导服务,核心服务,其他服务。

引导服务作用
Installer系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
ActivityManagerService负责四大组件的启动、切换、调度。
PowerManagerService计算系统中和Power相关的计算,然后决策系统应该如何反应
LightsService管理和显示背光LED
DisplayManagerService用来管理所有显示设备
UserManagerService多用户模式管理
SensorService为系统提供各种感应器服务
PackageManagerService用来对apk进行安装、解析、删除、卸载等等操作
核心服务 
BatteryService管理电池相关的服务
UsageStatsService收集用户使用每一个APP的频率、使用时常
WebViewUpdateServiceWebView更新服务
其他服务 
CameraService摄像头相关服务
AlarmManagerService全局定时器管理服务
InputManagerService管理输入事件
WindowManagerService窗口管理服务
VrManagerServiceVR模式管理服务
BluetoothService蓝牙管理服务
NotificationManagerService通知管理服务
DeviceStorageMonitorService存储相关管理服务
LocationManagerService定位管理服务
AudioService音频相关管理服务
….

这里举例看下 ActivityManagerService 的启动过程:

    private void startBootstrapServices() {
        ...
        ...
        Installer installer = mSystemServiceManager.startService(Installer.class);
        traceEnd();

        ...
        ...

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

这里调用了 SystemServiceManager 中的 startService 方法,这里的返回是 ActivityManagerService,所以对应的代码是:

    @SuppressWarnings("unchecked")
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
            throw new RuntimeException("Failed to create service " + className
                    + ": service class not found, usually indicates that the caller should "
                    + "have called PackageManager.hasSystemFeature() to check whether the "
                    + "feature is available on this device before trying to start the "
                    + "services that implement it", ex);
        }
        return startService(serviceClass);
    }

从这个方法的参数,可以推出 ActivityManagerService.Lifecycle.class 返回的是 String 类型的 className,从而得到了 Class 类型的 serviceClass,并再次调用另外一个 startService 方法:

    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

这么多代码,最终又调用了另外一个 startService:

    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

将传入的 SystemService 通过 mServices.add(service) 加入 mServices 中,而 mServices 是一个 ArrayList,这是为了方法对系统服务进行管理:

 private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();

通过调用 service.onStart() 来启动对应 SystemService,在 ActivityManagerService 中:

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

start() 方法如下:

    private void start() {
        removeAllProcessGroups();
        mProcessCpuThread.start();

        mBatteryStatsService.publish();
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
        // Wait for the synchronized block started in mProcessCpuThread,
        // so that any other acccess to mProcessCpuTracker from main thread
        // will be blocked during mProcessCpuTracker initialization.
        try {
            mProcessCpuInitLatch.await();
        } catch (InterruptedException e) {
            Slog.wtf(TAG, "Interrupted wait during start", e);
            Thread.currentThread().interrupt();
            throw new IllegalStateException("Interrupted wait during start");
        }
    }

这里就不继续去分析这两万多行代码的 ActivityManagerService,继续回到 SystemServer 的 run 方法:

            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);


            ...    
            ...
            Looper.loop();

初始化当前线程的 Looper,并调用 Looper.loop() 开启消息循环。

做完以上流程后,不免有个疑问,不是系统启动流程吗?桌面还没起来,起了一堆的系统服务起来,那接下来呢,哪里才是进行下一步呢?

在 startOtherServices() 方法中,存在以下代码:

        mActivityManagerService.systemReady(() -> {
            ...
            ...
        }, BOOT_TIMINGS_TRACE_LOG);

这里先不分析这个方法里面做了什么事情,先分析这个方法:

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    ...
    ...
    startHomeActivityLocked(currentUserId, "systemReady");
    ...
    ...
}

传入的是一个线程,所以在上面的方法中省略的部分是线程的 run 方法,从命名上看,这是调用 SystemReady 后的一个回调,而核心是 ActivityServiceManager 中的 systemReady 方法,并且调用了 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.instr == null) {
                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
                // For ANR debugging to verify if the user activity is the one that actually
                // launched.
                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
            }
        } else {
            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
        }

        return true;
    }

启动页面的 Intent 由方法 getHomeIntent() 获取:

构造一个带有HOME category的Intent,用此intent来从PackageManagerService查询对应的 ActivityInfo

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

 当获取到要启动的 Intent 后,调用  mActivityStartController.startHomeActivity,此方法在类 ActivityStartController 中:

    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
        mSupervisor.moveHomeStackTaskToTop(reason);

        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .execute();
        mLastHomeActivityStartRecord = tmpOutRecord[0];
        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();
        }
    }

调用的 obtainStarter 方法,obtainStarter是一个使用装饰者模式的方法,其含义是在对目标设置了几个参数之后,统一execute。

参考:

https://www.jianshu.com/p/35e66fe56a58

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值