Android启动过程 - SystemServer

一、SystemServer的启动

从上文得知,SystemServer的启动源头,在于Zygote进程在fork新进程后,执行了SystemServer的main方法。

platform/frameworks/base/services/java/com/android/server/SystemServer.java

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

首先,看下SystemServer构造方法:

public SystemServer() {
    // Record process start information.
    mStartCount = SystemProperties.getInt(SYSPROP_START_COUNT, 0) + 1;
    mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
    mRuntimeStartUptime = SystemClock.uptimeMillis();
    Process.setStartTimes(mRuntimeStartElapsedTime,         mRuntimeStartUptime, mRuntimeStartElapsedTime, mRuntimeStartUptime);

    // Remember if it's runtime restart or reboot.
    mRuntimeRestart = mStartCount > 1;
}

分别从elapsedRealtime和uptimeMillis两个方式记录了SystemServer的启动时间,保存在了Process中,同时记录了启动次数mStartCount。

继续看run方法:

private void run() {
    // 在System Propertie中记录启动时间
    SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
    SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
    SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));
    
    // SystemServer中只能发送oneway的binder请求
    Binder.setWarnOnBlocking(true);
    // SYNC_MODE_FULL模式确保每次数据库再进一步操作前,所有数据已保存到磁盘
    SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
    
    ...
    // 临时取消虚拟机GrowthLimit,这样在SystemServer启动过程中不会频繁触发GC,降低启动效率
    VMRuntime.getRuntime().clearGrowthLimit();
    // 收集下参数后设置"ro.build.fingerprint"值到SystemProperties
    Build.ensureFingerprintProperty();
    // 没有明确指定一个用户的前提下,SystemServer内部不可以访问Environment相关的path目录
    Environment.setUserRequired(true);
    // SystemServer内部拒绝呼入(incoming)的Bundles
    BaseBundle.setShouldDefuse(true);
    ...
    //
    // 重新设置SystemServer的Binder Thread数(31个)
    BinderInternal.setMaxThreads(sMaxBinderThreads);

    // 设置线程优先级(-2)
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
    // 如果在本进程内将线程优先级设置低于ANDROID_PRIORITY_BACKGROUND(值>10)则抛出异常
    android.os.Process.setCanSelfBackground(false);
    Looper.prepareMainLooper();
    Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
                    
    ...
    // 加载native的SystemServer
    System.loadLibrary("android_servers");
    // 打开heapprofd性能分析数据采集(debug模式下)
    initZygoteChildHeapProfiling();
    // 创建一个线程,定期检查fd数量。超过阈值则启用fdtrack
    if (Build.IS_DEBUGGABLE) {
        spawnFdLeakCheckThread();
    }
    // 如果上次shutdown失败,重新尝试shutdown
    performPendingShutdown();
    // 创建上下文
    createSystemContext();
    // 初始化各种主线模块    ActivityThread.initializeMainlineModules();
    
    // 创建SystemServiceManager
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
    
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    
    SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
    ...
    // Start services.
    try {
    	t.traceBegin("StartServices");
        // 启动关键引导服务 AMS、PMS等
    	startBootstrapServices(t);
        // 启动基础服务 BatteryService等
    	startCoreServices(t);
        // 其他一些服务
    	startOtherServices(t);
    	startApexServices(t);
    	// Only update the timeout after starting all the services so that we use
    	// the default timeout to start system server.
    	updateWatchdogTimeout(t);
    } catch (Throwable ex) {
    	Slog.e("System", "******************************************");
    	Slog.e("System", "************ Failure starting system services", ex);
    	throw ex;
    } finally {
    	t.traceEnd(); // StartServices
    }
    ...
    // 初始化严苛模式
    StrictMode.initVmDefaults(null);
    
    Looper.loop();
}

从run方法中,我们看到SystemServer的启动主要做了以下工作:

  1. 进行启动时间、日志、heapprofd、严苛模式等性能采集相关的基本设置,以及进程优先级、binder、虚拟机内存等保障SystemServer正常运行的基本设置。
  2. 创建SystemContext上下文
  3. 创建SystemServiceManager,通过startBootstrapServices(关键引导服务)、startCoreServices(核心服务)、startOtherServices(其他各路混杂的服务)、startApexServices等启动各类服务
  4. 启动looper。

二、服务管理

在startBootstrapServices、startCoreServices、startOtherServices、startApexServices中,对各类服务进行了启动,比如我们常见的ActivityManagerService、PackageManagerService、BatteryService等等,共近百个Service。而对Service启动的方式是相似的,以startBootstrapServices为例:

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    ...
    final Watchdog watchdog = Watchdog.getInstance();
    watchdog.start();
    
    SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
    
    PlatformCompat platformCompat = new PlatformCompat(mSystemContext);
    ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
    ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
                new PlatformCompatNative(platformCompat));
    ...
    Installer installer = mSystemServiceManager.startService(Installer.class);
    ...
    ActivityTaskManagerService atm =     mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    ...
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    ...
}

而在startOtherServices中,对有这样一些处理:

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    ...
    ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
    mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
    wm = Window 
new PhoneWindowManager(),     mActivityManagerService.mActivityTaskManager);
    ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
    mActivityManagerService.setWindowManager(wm);
    ...
    mSystemServiceManager.startServiceFromJar(
                        WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
    ...
}

startOtherServices处理服务其他三个方法庞杂综上SystemServer服务管理主要以下方式

  • mSystemServiceManager.startService -- 启动一个服务
  • mSystemServiceManager.startBootPhase -- 广播所有启动服务当前的启动阶段
  • ServiceManager.addService -- 服务纳入ServiceManager进行管理

ServiceManager是一个handler0binder service服务addServer(key, service)到ServiceManager可以通过key轻松获取对应服务所有SystemServer启动Service加入ServiceManager因此后续直接通过key获取到对应Service的binder服务端

SystemServiceManagerSystemServer本地集中启动、管理Service的管理所有Service必须继承SystemService

看下SystemService的接口

platform/frameworks/base/services/core/java/com/android/server/SystemService.java

public abstract class SystemService {
    ...
    public abstract void onStart();
    public void onBootPhase(@BootPhase int phase) {}
    ...
}

看下SystemServiceManagerstartService

SystemServiceManager(Context context) {
        mContext = context;
        mServices = new ArrayList<>();
        mServiceClassnames = new ArraySet<>();
        mNumUserPoolThreads = Math.min(Runtime.getRuntime().availableProcessors(),
                DEFAULT_MAX_USER_POOL_THREADS);
    }

public <T extends SystemService> T startService(Class<T> serviceClass) {
    if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
        try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
        }
        ...
        startService(service);
    }
}

public void startService(@NonNull final SystemService service) {
        String className = service.getClass().getName();
        if (mServiceClassnames.contains(className)) {
            Slog.i(TAG, "Not starting an already started service " + className);
            return;
        }
        mServiceClassnames.add(className);

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

startService过程就是通过Class反射构建Service对象然后调用onStart方法

过程使用mServiceClassnamesmServices两个集合缓存Service相关信息mServiceClassnames用于避免重复启动mServices用于存储所有service相应时候集中处理比如startBootPhase方法广播所有service当前进入启动阶段

public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
    if (phase <= mCurrentPhase) {
		throw new IllegalArgumentException("Next phase must be larger than previous");
	}
	mCurrentPhase = phase;

	Slog.i(TAG, "Starting phase " + mCurrentPhase);
	try {
		t.traceBegin("OnBootPhase_" + phase);
		final int serviceLen = mServices.size();
		for (int i = 0; i < serviceLen; i++) {
			final SystemService service = mServices.get(i);
			long time = SystemClock.elapsedRealtime();
			t.traceBegin("OnBootPhase_" + phase + "_" + service.getClass().getName());
			try {
				service.onBootPhase(mCurrentPhase);
			} catch (Exception ex) {
				throw new RuntimeException("Failed to boot service "
						+ service.getClass().getName()
						+ ": onBootPhase threw an exception during phase "
						+ mCurrentPhase, ex);
			}
			warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");
			t.traceEnd();
		}
	} finally {
		t.traceEnd();
	}

	if (phase == SystemService.PHASE_BOOT_COMPLETED) {
		final long totalBootTime = SystemClock.uptimeMillis() - mRuntimeStartUptime;
		t.logDuration("TotalBootTime", totalBootTime);
		SystemServerInitThreadPool.shutdown();
	}
}

所有serviceonBootPhase调用

对于startBootPhase使用场景举个例子

在系统启动动画播放完成后,ActivityManagerService会finishBooting调用startBootPhase,通知所有其他service当前进入这个PHASE_BOOT_COMPLETED状态

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

final void finishBooting() {
    ...
    // Let system services know.
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED);
    ...
}

如果监听PHASE_BOOT_COMPLETED这个阶段可以onBootPhase判断phase比如

platform/frameworks/base/services/core/java/com/android/server/StorageManagerService.java

public void onBootPhase(int phase) {
            if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
                mStorageManagerService.servicesReady();
            } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
                mStorageManagerService.systemReady();
            } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
                mStorageManagerService.bootCompleted();
            }
        }

startBootPhase -> onBootPhase设计,是对Service之间、以及Service对系统各阶段依赖性一个处理启动过程中各阶段的优化工作一个切入点

使用一个并不严谨大致表现角色关系

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值