Android实训(二):SystemService创建过程、fork、启动阶段和自定义服务

Android实训(二):SystemService创建过程、fork、启动阶段和自定义服务,第1张

SystemServer

systemServer是由zygote进程fork出来的进程,它分配所有的服务

1.基础理论 1.1 fork

fork用于创建一个新进程,它和原来的进程同时运行,原进程为父进程,一般情况而言,子进程和父进程的大部分值相同,少部分值不同,可以看作是进程的克隆

fork()的返回值不同代表内容不同

负值:创建子进程失败,一般失败是因为进程的数量达到上限和内存不足

零:返回到新创建的子进程

正值:返回父进程,并伴随子进程的进程ID

进程调用fork后转入内核,有以下 *** 作:

  1. 分配新的内存块和内核数据结构给子进程
  2. 将父进程的数据结构等拷贝给子进程
  3. 将子进程放入系统的进程列表中
  4. fork返回开始调度器调度
1.2 反射

java的反射机制详见

java的注解和反射:自定义注解,java内存机制,类加载器,反射获得对象方法和注解_michilay的博客-CSDN博客

2.原理

SystemServer是Android中重要的进程,常见的WMS(android.display)、AMS、PMS等,都是以一个线程的方式存在于SystemServer进程中。此进程在系统中的名称为“system_server”。它负责启动系统的各项服务,大体有以下几个过程:

  • 初始化一些零碎事务
  • createSystemContext初始化system_server进程的context
  • startBootstrapServices启动系统Boot级别服务
  • startCoreServices启动系统级别核心服务
  • startOtherServices启动其他类型服务,包括厂家定制服务

也就是说,SystemServer先初始化,接着分别启动Boot级别,核心级别和其他级别的服务,在这个过程中,SystemServiceManager的startBootPhase()非常重要

//通过命令查看它的进程号
ps -A | grep system_server

SystemServer启动流程

1:Zygote通过ZygoteInit来fork出SystemServer进程
2:fork出的的子进程在handleSystemServerProcess里开始初始化
3-6:调用zygoteInit方法,重定向log输出,通用的初始化等;调用Native层代码,启动Binder线程池,从而SystemServer进程就可以使用Binder与其他进程进行通信;进入SystemServer的main方法
7-9:设置虚拟机的内存利用率参数值,继续调用invokeStaticMain方法通过反射得到SystemServer类,并找到SystemServer中的main方法,然后将main方法传入MethodAndArgsCaller异常中抛出,ZygoteInit.java的main方法捕获,多用SystemServer的main方法
11-15:运行SystemServer进程

站在框架的角度来看,Zygote启动了SystemServer,它帮助我们创建了很多例如AMS、PMS、WMS等关键服务,同时,ServiceManager使用静态方法addService将这些关键服务放到ServiceManager中,当App层的Laucher等应用需要使用时直接调用

代码位于

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

3.服务介绍 3.1 Boot级别服务: starBootstrapServices,一共有十二个核心服务

Installer负责安装apk

AMS负责四大组件的启动切换调度等

PMS负责电源管理

LightsService负责指示灯

DisplayManagerService管理显示设备

PMS负责apk安装解析验证升级等工作

3.2 Core级别服务: startCoreServices,一共有四个服务

BatteryService负责电池管理需要LightService

UsageStatsService收集用户使用APP的频率和时长

WebViewUpdateService检测是否有可更新的Webview

BinderCallsStatsService跟踪Binder调用的CPU时间小号

3.3 Other级别服务: startOtherServcies,共有几十个服务

BluetoothService蓝牙相关

WifiService负责Wife

此方法经历了五个启动阶段

SystemService.PHASE_LOCK_SETTINGS_READY
SystemService.PHASE_SYSTEM_SERVICES_READY
SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY
SystemService.PHASE_ACTIVITY_MANAGER_READY
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START

在完成了这些阶段之后,会调用AMS的systemReady()方法,调用startHomeActivityLocked来启动桌面应用

启动完桌面后,会返回到SystemServer的run方法,会调用Looper.loop()

等待其他线程Handler发送消息

3.4 启动阶段

SystemServer经历了上述三个阶段需要一个值来排序,SystemServiceManager提供了startBootPhase()贯穿了所有的进程启动过程

debug日志中可以看到数字的进度,方便调试

4.调试方法

使用adb查看logcat可以查看各个server启动所耗时间

adb logcat | grep -i systemserver
5.自定义服务
  • 在源码LINUX/android/packages/services/Car/tests/下新建文件夹

  • 起名TestServcie,新建src和Android.mk文件

  • src目录下有java.com.example.test.TestServcie.java

  • java文件代码如下

    public class TestServcie extends SystemService{
    	public static final String TAG = "Test Service";
        public TestService(Context context){
            super(context);
            Log.d(TAG,"测试服务被构建");
        }
        @Override
        public void onStart()
        {
            Log.d(TAG,"测试服务开始");
        }}
    
  • Android.mk文件内容如下

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE_TAGS := optional
    LOCAL_SRC_FILES += $(call all-java-files-under,src)
    LOCAL_JAVA-LIBRARIES := services
    LOCAL_MODULE := TestService
    LOCAL_PROGUARD_ENABLED := disabled
    include $(BUILD_JAVA-LIBRARY)
    
  • 修改SystemServer代码

    在SystemServer中搜索"CAR_SERVICE_HELPER_SERVICE_CLASS"仿照其内容在下面写上

    privte static final String TEST SERVICE_CLASS = "com.example.test.TestService"
    

    在另一个位置上也要加上相似代码

    traceBeginAndSlog("StartTestService");
    mSystemServiceManager.startService(TEST_SERVICE_CLASS);
    traceEnd();
    
  • 修改core.mk

    为了参与编译,在build/make/target/product/core.mk中搜索"PRODUCT_PACKAGES",将TestService添加进去,参加编译

    并且在后面添加PRODUCT_SYSTEM_SERVER_JARS += TestService

  • 编译生效

  • 查看log

6.总结
  • Zygote调用startSS创建system_server进程
  • SS调用handleSystemServerProcess
  • 抛出异常,被ZygoteInit捕获后调用SS的main函数
  • main加载libandroid_server.so调用nativ_init方法
  • 启动三个关键阶段
  • 进入消息循环

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/874123.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存