• Android(java)学习笔记104:Framework运行环境之启动SystemServer进程


    1. SystemServer进程     

      SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的。与启动普通进程的差别在于:类zygote为启动SystemServer提供专门的函数startSystemServer(),而不是标准的forAndSpecilize函数。同时,SystemServer进程启动后首先要做的事情和普通进程也有所差别。

        函数startSystemServer()的关键功能如下:

    (1)定义一个String[]数组,数组中包含了要启动进程的相关信息,其中最后一项指定新进程启动后装载的第一个Java类,此处就是为类com.android.SystemServer

    (2)调用forkSystemServer()从当前的zygote进程孵化新的进程。该函数是一个native函数,其作用与folkAndSpecilize()相似

    (3)启动新进程后,在函数handleSystemServerProcess()中主要完成如下两件事件

           1.关闭Socket服务器

           2.执行com.android.server.SystemServer类中函数main()。

    除了这两个主要事情外,还做了一些额外的运行环境配置,这些配置主要在函数commonInit()和函数zygoteInitNative()中完成。一旦配置好SystemServer的进程环境后,就从类SystemServer中main()函数开始运行。

    2. 启动各种系统服务线程

             SystemServer进程在Android的运行环境中扮演了"中枢"的作用,在APK应用中能够直接交互的大部分系统服务都在这个进程中运行,例如WindowManagerServer(Wms)、ActivityManagerSystemServive(AMS)、PackageManagerServer(PMS)等常见的应用,这些系统服务都是以一个线程的方式存在与SystemServer进程之中。下面就来介绍都有哪些服务进程,及其启动的顺序。

             SystemServer中的main()函数首先调用的是函数init1(),这是一个native函数,内部会进行一些与Dalvik虚拟机相关的初始化工作。该函数执行完毕后,其内部会调用Java端的init2()函数,这就是为什么Java源码中没有引用init2()的地方,主要的系统服务都是在init2()函数中完成。

            该函数首先创建了一个ServerThread对象,该对象是一个线程,然后直接运行该线程,从ServerThread的run()方法内部开始真正启动各种服务线程。基本上每个服务都对应的Java类,从编码规范的角度来看,启动这些服务模式可归类为如下三种:

            (1)模式1:是指直接使用构造函数构造一个服务,由于大多数服务都对应一个线程,因此,在构造函数内部就创建一个线程并自动运行。

            (2)模式2:是指服务类会提供一个getInstance()方法,通过该方法获取该服务对象,这样的好处是保证系统中仅包含一个该服务对象。

            (3)模式3:是指服务类的main()函数中开始执行。

    SystemServer中启动服务列表:

    服务类名称

    作用描述

    启动模式

    EntropyService

    提供伪随机数

    1.0

    PowerManagerService

    电源管理服务

    1.2/3

    ActivityManagerService

    最核心的服务之一,管理 Activity

    自定义

    TelephonyRegistry

    通过该服务注册电话模块的事件响应,比如重启、关闭、启动等

    1.0

    PackageManagerService

    程序包管理服务

    3.3

    AccountManagerService

    账户管理服务,是指联系人账户,而不是 Linux 系统的账户

    1.0

    ContentService

    ContentProvider 服务,提供跨进程数据交换

    3.0

    BatteryService

    电池管理服务

    1.0

    LightsService

    自然光强度感应传感器服务

    1.0

    VibratorService

    震动器服务

    1.0

    AlarmManagerService

    定时器管理服务,提供定时提醒服务

    1.0

    WindowManagerService

    Framework 最核心的服务之一,负责窗口管理

    3.3

    BluetoothService

    蓝牙服务

    1.0 +

    DevicePolicyManagerService

    提供一些系统级别的设置及属性

    1.3

    StatusBarManagerService

    状态栏管理服务

    1.3

    ClipboardService

    系统剪切板服务

    1.0

    InputMethodManagerService

    输入法管理服务

    1.0

    NetStatService

    网络状态服务

    1.0

    NetworkManagementService

    网络管理服务

    NMS.create()

    ConnectivityService

    网络连接管理服务

    2.3

    ThrottleService

    暂不清楚其作用

    1.3

    (续表)

     

    服务类名称

    作用描述

    启动模式

    AccessibilityManagerService

    辅助管理程序截获所有的用户输入,并根据这

    些输入给用户一些额外的反馈,起到辅助的效果

    1.0

    MountService

    挂载服务,可通过该服务调用 Linux 层面的 mount 程序

    1.0

    NotificationManagerService

    通知栏管理服务, Android 中的通知栏和状

    态栏在一起,只是界面上前者在左边,后者在右边

    1.3

    DeviceStorageMonitorService

    磁盘空间状态检测服务

    1.0

    LocationManagerService

    地理位置服务

    1.3

    SearchManagerService

    搜索管理服务

    1.0

    DropBoxManagerService

    通过该服务访问 Linux 层面的 Dropbox 程序

    1.0

    WallpaperManagerService

    墙纸管理服务,墙纸不等同于桌面背景,

    在 View 系统内部,墙纸可以作为任何窗口的背景

    1.3

    AudioService

    音频管理服务

    1.0

    BackupManagerService

    系统备份服务

    1.0

    AppWidgetService

    Widget 服务

    1.3

    RecognitionManagerService

    身份识别服务

    1.3

    DiskStatsService

    磁盘统计服务

    1.0

      
     

    AmS的启动模式如下:

    调用main()函数,返回一个Context对象,而不是AmS服务本身。

    调用AmS.setSystemProcess()。

    调用AmS.installProviders()。

    调用systemReady(),当AmS执行完systemReady()后,会相继启动相关联服务的systemReady()函数,完成整体初始化。

    备注:

    ystemServer是Android系统的一个核心进程,它是由zygote进程创建的,因此在android的启动过程中位于zygote之后。android的所有服务循环都是建立在 SystemServer之上的。在SystemServer中,将可以看到它建立了android中的大部分服务,并通过ServerManager的add_service方法把这些服务加入到了ServiceManager的svclist中。从而完成ServcieManager对服务的管理。

    先看下SystemServer的main函数:

     

    [java] view plaincopy
     
    1. native public static void init1(String[]args);  
    2. public static void main(String[] args) {  
    3.        if(SamplingProfilerIntegration.isEnabled()) {  
    4.           SamplingProfilerIntegration.start();  
    5.            timer = new Timer();  
    6.            timer.schedule(new TimerTask() {  
    7.                @Override  
    8.                public void run() {  
    9.                   SamplingProfilerIntegration.writeSnapshot("system_server");  
    10.                }  
    11.            }, SNAPSHOT_INTERVAL,SNAPSHOT_INTERVAL);  
    12.        }  
    13.        // The system server has to run all ofthe time, so it needs to be  
    14.        // as efficient as possible with itsmemory usage.  
    15.       VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);  
    16.       System.loadLibrary("android_servers"); //加载本地库android_servers  
    17.        init1(args);  
    18.    }  

     

    在main函数中主要是调用了本地方法init1(args), 他的实现位于../base/services/jni/com_android_server_SystemService.cpp中

    [java] view plaincopy
     
    1. static voidandroid_server_SystemServer_init1(JNIEnv* env, jobject clazz)  
    2. {  
    3.     system_init();  
    4. }  

       进一步来看system_init,在这里面看到了闭合循环管理框架:

    [java] view plaincopy
     
    1. runtime->callStatic("com/android/server/SystemServer","init2");//回调了SystemServer.java中的init2方法  
    2.     if (proc->supportsProcesses()) {  
    3.         LOGI("System server: enteringthread pool. ");  
    4.        ProcessState::self()->startThreadPool();  
    5.        IPCThreadState::self()->joinThreadPool();  
    6.         LOGI("System server: exitingthread pool. ");  
    7.     }  

     

    通过调用com/android/server/SystemServer.java中的init2方法完成service的注册。在init2方法中主要建立了以ServerThread线程,然后启动线程来完成service的注册。

    [java] view plaincopy
     
    1. public static final void init2() {  
    2.     Slog.i(TAG, "Entered the Androidsystem server!");  
    3.     Thread thr = new ServerThread();  
    4.    thr.setName("android.server.ServerThread");  
    5.     thr.start();  
    6. }  

    具体实现service的注册在ServerThread的run方法中:

    [java] view plaincopy
     
    1.  try {  
    2.             Slog.i(TAG, "EntropyService");  
    3.            ServiceManager.addService("entropy", new EntropyService());  
    4.             Slog.i(TAG, "PowerManager");  
    5.             power = new PowerManagerService();  
    6.            ServiceManager.addService(Context.POWER_SERVICE, power);  
    7.             Slog.i(TAG, "ActivityManager");  
    8.             context =ActivityManagerService.main(factoryTest);  
    9.             Slog.i(TAG, "TelephonyRegistry");  
    10.            ServiceManager.addService("telephony.registry", newTelephonyRegistry(context));  
    11.   
    12. }  

    3. 启动第一个Activity:

           当启动以上服务线程后,ActivityManagerService(AMS)服务是以systemReady()调用完成最后启动的,而在AmS的函数systemReady()内部的最后一段代码则发出启动任务队列中最上面一个Activity的消息。因为在系统刚启动时,mMainStack队列中并没有任何Activity对象,所以在类AcitivityStack中将调用startHomeActivityLocked()。

           开机后,系统从哪个Activity开始执行这一动作,完全取决于mMainStack队列中的第一个Activity对象。如果在ActivityManagerServer启动时能够构造一个Activity对象(并不是说构造出一个Activity类的对象),并将其放到mMainStack队列中,那么第一个运行的Activity对象就是这个Activity,这一点不像其他操作系统中通过设置一个固定程序作为第一个启动程序。

          在Ams的startHomeAcitivityLocked()中,系统发出一个catagory字段包含CATEGORY_HOME的intent。

          无论是哪个应用程序,只要声明自己能够响应该intent,那么就可以被认为是Home程序,这是为什么在Android领域会存在各种"Home程序"的原因。系统并没有任何程序赋予"Home"特权,而只是把这个权利交给了用户。当在系统中有多个程序能够响应该intent时,系统会弹出一个对话框,请求用户选择启动哪个程序,并允许用户记住该选择,从而使得以后每次按Home都会启动相同Activity,这就是第一个Acitivity的启动过程。

  • 相关阅读:
    Informix日期获取上周上月昨天去年SQL
    Oracle-创建一个DBLink的方法
    Kafka-Partitions与Replication Factor 调整准则
    Linux-删除文件空间不释放问题解决
    Redhat7-Oracle-sqlldr-安装配置
    Centos7-安装oracle客户端11.2.0.4
    Centos7-单机安装jumpserver
    Redhat6.4-yum本地源安装配置
    Linux-zip unzip 命令日常使用
    xxl-job日志
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4732260.html
Copyright © 2020-2023  润新知