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

文章详细阐述了Android系统中SystemServer进程的核心服务启动过程,从`SystemServer.run`开始,包括`Looper.prepareMainLooper`、`System.loadLibrary`、`createSystemContext`、`ActivityThread.attach`等步骤,直至`Looper.loop`进入消息循环。在此过程中,系统服务如AMS、PMS和WMS等被启动,同时介绍了ContextImpl、Application和Instrumentation的创建。整个启动流程涉及Android系统的各个关键组件和服务。

目录

前言

一. 核心服务启动

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 部分;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值