AOSP 8.0 系统启动之五systemserver启动(三)

目录

前言

一. 核心服务启动

1.1 SystemServer.run

1.1.1  Looper.prepareMainLooper

1.1.2 System.loadLibrary

1.1.3 createSystemContext

1.1.4 ActivityThread.systemMain

1.1.5 ActivityThread.attach

1.1.6 ActivityThread.getSystemContext()

1.1.7 startBootstrapServices

1.1.8 startCoreServices

1.1.9 startOtherServices

1.1.10 startSystemUi

1.1.10 Looper.loop

        二、总结


前言

通过之前进程启动系列文章从Init到Zygote一路启动到SystemServer的过程。 

SystemServer是Android系统中重要的进程,系统中主要的服务驻留在其中:
常见的比如WindowManagerServer(WMS),ActivityManagerService(AMS),
PackageManagerServer(PMS),这些系统服务都存在于SystemServer进程中,并且将一些进程通过调用ServiceManager 的静态方法addService,将service放到ServiceManager进程(服务大管家)。当App需要使用这些服务时可能调用ServiceManager的 getService方法获取到它们。
因此,SystemSever负责启动系统的各项服务,Android系统中Java世界的核心 Service都会在这里启动并工作;

涉及源码

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

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

frameworks/base/core/java/android/app/
  - ActivityThread.java
  - LoadedApk.java
  - ContextImpl.java

一. 核心服务启动

大致流程如下:

SystemServer.main
    SystemServer.run
        Looper.prepareMainLooper()
        System.loadLibrary()
        createSystemContext
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
            startSystemUi
        Looper.loop();

接下来,从其main方法说起

1.1 SystemServer.run

public final class SystemServer {
    public static void main(String[] args) {
        new SystemServer().run();
    }
    
    private void run() {
        try {
            //getprop persist.sys.dalvik.vm.lib.2     libart.so
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
            ......
            //保证当前进程的优先级较高,始终处于可被尽快调度
            // Ensure binder calls into the system always run at foreground priority.
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
            BinderInternal.setMaxThreads(sMaxBinderThreads); //31 个线程

            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);    

            // Prepare the main looper thread (this thread).
            Looper.prepareMainLooper();
            // Initialize native services.
            System.loadLibrary("android_servers");
            // Initialize the system context.
            createSystemContext();
    
            ......
        } finally {
         
        }
        //启动各种核心服务,ams,pms,wms等
        startBootstrapServices();  
        startCoreServices();
        startOtherServices();
        //安装系统Providers
    	mActivityManagerService.installSystemProviders();	
        // Loop forever.  system_server 进程一般不会退出,否则就会重启zygote 进程
        Looper.loop();
        //执行到这句代码,意味着looper 跳出, main函数运行结束, 当前线程就结束, 进程死亡
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

1.1.1  Looper.prepareMainLooper

        暂时跳过,后续Looper专题会补充

1.1.2 System.loadLibrary

        暂时跳过,后续JNI 专题会补充

1.1.3 createSystemContext

在SystemServer的run函数中,在启动AMS之前,调用了createSystemContext函,主要用来是初始化 System Context和SystemUi Context,并设置主题

调用createSystemContext 完毕后,完成以下内容

  • 得到一个ActivityThread对象,代表当前进程(此时为系统进程)的主线程
  • 得到一个Context对象,对SystemServer而言,它包含的application运行环境与framewokr-res.apk有关
private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();  //第一次出现activityThread对象,此处并不是线程的概念,只是一个对象而已 
    
    //获取system context
    mSystemContext = activityThread.getSystemContext();
    //设置系统主题
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
 
    //获取systemui context
    final Context systemUiContext = activityThread.getSystemUiContext();
    //设置systemUI 主题
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

createSystemContext()创建了两个上下文,系统context和SystemUi context。这两个挺重要,会传入AMS中,这里就是它们创建的地方。

1.1.4 ActivityThread.systemMain

//ActivityThread.java
public static ActivityThread systemMain() {
    
    //获取ActivityThread对象
    ActivityThread thread = new ActivityThread(); 
    thread.attach(true, 0); 
    return thread;
}

ActivityThread 对象创建,且这里并没有创建线程,核心函数是attach,因为SystemServer中也运行着一些系统APK,例如framewor-res.apk,SettingsProvider.apk,因此SystemServer也可以看作是一个特殊的应用进程。

1.1.5 ActivityThread.attach

对于系统进程而言,ActivityThread的attach函数最重要的工作,就是创建Instrumentation,Application和Context
attach(true,0) 这里走的是系统进程(应用启动也会走,system为false走的是应用进程),创建ActivityThread中的重要成员:Instrumentation、 Application 和 Context

private void attach(boolean system, long startSeq) {
    mSystemThread = system;
    //传入的system为0
    if (!system) {
        //应用进程的处理流程
        ...
    } else {
        //系统进程的处理流程,该情况只在SystemServer中处理
        //创建ActivityThread中的重要成员:Instrumentation、 Application 和 Context
        mInstrumentation = new Instrumentation();
        mInstrumentation.basicInit(this);
        
        //创建系统的Context,
        ContextImpl context = ContextImpl.createAppContext(
                this, getSystemContext().mPackageInfo);
        
        //调用LoadedApk的makeApplication函数
        mInitialApplication = context.mPackageInfo.makeApplication(true, null);
        mInitialApplication.onCreate();
    }
    
}
ContextImpl context = ContextImpl.createAppContext(this,getSystemContext().mPackageInfo);
  • Instrumentation:很重要的基类,会优先其他类被初始化,系统先创建它,再通过它创建其他组件。允许检测系统与应用所有交互。应用AndroidManifest.xml标签定义实现。
  • Context:上下文,context是Android中的一个抽象类,用于维护应用运行环境的全局信息。通过Context可以访问应用的资源和类,甚至进行系统级操作,例如启动Activity,发送广播等。ActivityThread的attach函数中通过这行代码创建出应用对应的Context, 这里创建的是一个LoadApk(packagename是android,即framewor-res.apk),以此获取了Context对象
  • Application:保存应用的全局状态,在ActivityThread中,针对系统进程,通过下面的代码创建了初始的Application
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();


1.1.6 ActivityThread.getSystemContext()

public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            //调用ContextImpl的静态函数createSystemContext
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}


static ContextImpl createSystemContext(ActivityThread mainThread) {
    //创建LoadedApk类,代表一个加载到系统中的APK, 构造函数中的mApplicationInfo.packageName = "android"; mPackageName = "android";
    //注意此时的LoadedApk只是一个空壳
    //PKMS还没有启动,无法得到有效的ApplicationInfo,是主动new出来的
    LoadedApk packageInfo = new LoadedApk(mainThread);
 
    //拿到ContextImpl 的对象
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
            null, null);
     //初始化资源信息
    context.setResources(packageInfo.getResources());
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    return context;
}

createSysteContext的内容就是创建一个LoadApk,然后初始化一个ContextImpl对象。创建的LoadApk对应的packageName为’‘android’,也就是framewok-res.apk.由于该APK仅供SystemServer进程,因此创建的Context被定义为System Context,现在该LoadApk还没有得到frame-res.apk实际信息。当pkms启动,完成对应的解析后,ams将重新设置这个LoadedApk。

1.1.7 startBootstrapServices

private void startBootstrapServices() {
    //阻塞等待 和installd建立连接, 万一installd 断开会重连接
    Installer installer = mSystemServiceManager.startService(Installer.class); //Installer extends SystemService 
  
    mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();  //启动AMS
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);  //AMS 和 install建立关系

    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); //启动PMS
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    

    // Set up the Application instance for the system process and get started.
    //将framework-res.apk,的信息加入到SystemServer进程的LoadedApk中,并创建了SystemServer进程的ProcessRecord,加入到mPidSelfLocked由AMS统一管理。
    mActivityManagerService.setSystemProcess(); 
}


public void setSystemProcess() {
   try {
        .....
        //获取“android”应用的ApplicationInfo,并装载到mSystemThread
        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
        //创建ProcessRecord维护进程的相关信息
        synchronized (this) {
            ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                    false,
                    0,
                    new HostingRecord("system"));
            app.setPersistent(true);
            app.pid = MY_PID;//Process.myPid();
            app.getWindowProcessController().setPid(MY_PID);
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            mPidsSelfLocked.put(app);//
            mProcessList.updateLruProcessLocked(app, false, null);
            updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
        }
    } catch (PackageManager.NameNotFoundException e) {
        throw new RuntimeException("Unable to find android system package", e);
    }
}

1.1.8 startCoreServices

private void startCoreServices() {
    // Records errors and logs, for example wtf()  //稳定性相关的
    mSystemServiceManager.startService(DropBoxManagerService.class);
    ...
}

1.1.9 startOtherServices

AMS启动后的后续工作,主要调用systemReady() 方法中启动,systemui在goingCallback中完成,当桌面应用启动完成后,发送开机广播ACTION_BOOT_COMPLETED到此为止。

private void startOtherServices() {
	final Context context = mSystemContext;
	...
	WindowManagerService wm = null;

	.....
	mActivityManagerService.installSystemProviders(); 安装SettingsProvider.apk
	
	inputManager = new InputManagerService(context); //启动IMS,事件响应

	wm = WindowManagerService.main(context, inputManager,
	        mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
	        !mFirstBoot, mOnlyCore, new PhoneWindowManager()); //启动WMS

	mActivityManagerService.setWindowManager(wm);  //AMS & WMS 建立关系

	traceBeginAndSlog("StartInputManager");
	inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); //WMS & IMS建立关系
	inputManager.start(); //启动IMS,等待事件响应触发
	
	mActivityManagerService.systemReady(() -> {
	        ...
	        startSystemUi(context, windowManagerF); //启动systemUI 进程
	        ...
     }, BOOT_TIMINGS_TRACE_LOG);
}

AMS的systemReady
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
	synchronized(this) {
	    if (mSystemReady) {  //默认是false,不走这个分支
	        ....
	        if (goingCallback != null) {
	            goingCallback.run();
	        }
	        return;
	    }

	    ...
	    mSystemReady = true;
	    if (goingCallback != null) 
	    	goingCallback.run();
	    ...
	    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
	    .....
	    startHomeActivityLocked(currentUserId, "systemReady");
	}
}

1.1.10 startSystemUi


//启动SystemUI app进程
static final void startSystemUi(Context context, WindowManagerService windowManager) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.android.systemui",
                "com.android.systemui.SystemUIService"));
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    context.startServiceAsUser(intent, UserHandle.SYSTEM);
    windowManager.onSystemUiStarted();
}

1.1.10 Looper.loop

Systemserver进程进入死循环,靠底层的epoll机制来唤醒,并不是一直运行着,没有消息就处于休眠状态,不消耗CPU;

二、总结

APP相关的启动流程是 :Zygote -> SystemServer App -> systemUI App-> persist App -> Launcher App;

后面会针对进程启动过程中的一些知识点进行补充/晚上, 如binder通信,信号处理,以及进程&线程管理,还有JNI 部分;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值