android框架笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33487044/article/details/82117905

title: android框架笔记
comments: true
toc: true
date: 2018-03-15 09:02:05
tags:
- android

- framework

[TOC]
《Android框架揭秘》笔记。

Android框架概要

源代码结构

  • kernel – 内核
  • bionic – 标准C运行支持库
  • bootloader – 内核加载器参考
  • build – build系统
  • cts – 兼容性测试源
  • dalvik – 虚拟机
  • art – 虚拟机
  • external – 开放源
  • frameworks – 框架
  • hardware – HAL库源
  • packages – Android基本应用
  • system – 初始化进程、蓝牙工具集

通过启动过程分析framework

  1. bootloader加载Linux内核
  2. init进程
    • 运行Daemon(C/C++程序)
      • USB(usbd)
      • ADB(adbd)
      • Debugger(debugged)
      • Radio Interface Layer(rild)
    • 运行Context Manager(C/C++程序)
    • 运行Media Server(C/C++程序)
    • 运行Zygote(Java程序)
  3. Context Manager
    管理Android系统服务的重要进程,提供Android内的各种系统服务信息。
    系统启动时,Android所有系统服务要把各自的handle信息注册到Context Manager,Binder IPC用于进程间通信。

  4. Media Server – 本地服务注册
    运行基于C/C++的本地系统服务,如Audio Flinger,Camera等

  5. Zygote

    • 运行System Server
  6. System Server – Java服务注册
    • 创建Power Manager Service
    • 创建Sensor Service
    • 创建Location Service
    • 创建Connectivity Service
    • 创建Activity Manager Service
      • 运行HOME应用

源代码级别调试

导入源代码到AS
依赖源代码工程
断点调试HelloWorld程序

init进程

在用户空间启动init进程,再依次启动系统运行所需其他进程,系统启动完成后,init进程作为守护进程监视其他进程,监视中的进程终止时释放进程所占用的系统资源。

运行过程

init是内核启动的第一个用户级进程。

启动过程
  1. start_kernel()
  2. init_post()
  3. run_init_process() – 运行init进程。

源码分析

分析及运行init.rc文件

代码位置:/android/system/core/init/init.cpp

  • 分析init.rc文件
  • 分析/system/etc/init、/vendor/etc/init、/odm/etc/init文件
  • 执行early-init动作列表 – ActionManager.QueueEventTrigger()
  • 执行init动作列表 – ActionManager.QueueBuiltinAction()
  • 执行bootmode动作列表
  • 运行服务列表
生成设备驱动节点

代码位置:/android/system/core/init/init.cpp

  • 生成并装载目录
    • tmpfs(虚拟内存的文件系统) – /dev
    • devpts(虚拟终端文件系统) – /dev/pts
    • sysfs(特殊的文件系统) – /sys
    • proc(虚拟的文件系统) – /proc
    • selinuxfs(虚拟的文件系统) – /sys/fs/selinux(se: security enhanced)

初化内核记录器,重定向stdin/stdout/stderr到/dev/null。
Unix类系统中,所有输入输出被视为文件,标准输入为0,标准输出为1,标准错误输出为2。

  • 生成设备静态节点 – SetInitAvbVersionInRecovery()
  • 初始化SELinux – selinux_initialize()
  • 注册POLL事件
处理子进程终止

详细代码位置:/android/system/core/init/signal_handler.cpp

  • 注册SIGCHLD信号handler – signal_handler_init();
  • 生成UDS(Unix Domain Sockets)套接字
  • 注册POLL事件
属性服务
  • 属性初始化 – property_init()
  • 属性初始化设置 – property_set属性更改只能在init进程中执行
  • 运行属性服务 – start_property_service();
  • 注册POLL事件

init.rc脚本文件分析与执行

init.rc用来设置系统环境,记录待执行的进程。
init.rc脚本使用AIL(Android Init Language)编写。
AIL语言详细介绍:/android/system/core/init/README.md。

文件结构

文件以行为单位,用空格分隔标识符,#号标示注释。使用C语言格式的反斜杠转义字符插入空白,双引号用来避免空白符分隔标识符。末尾的反斜杠表示折行。

动作和服务隐式声明新区域,所有的命令或配置属于最近声明的区域,区域开始前的命令或配置将被忽略。
动作和服务要求唯一性,动作以最先声明的为准,重复声明的服务将被忽略并无性繁殖错误日志。

  • actions – 动作,以on开头
    拥有触发器来决定何时执行命令。
on {trigger} [&& {trigger}]*
    {command}
    {command}
  • service – 服务
    init进程启动的服务,配置服务退出时是否需要重启。
service {servicename} {servicepath} [{argument}]*
    {option}
    {option}
  • option – 配置
    配置基于服务的,描述init进程何时如何运行服务。

    • console – 服务需要控制台,默认值为default。
    • critical – 设备关键性服务,在四分钟内退出超过四次,设备将重启进入恢复模式
    • disabled – 服务不会自行启动
    • setenv – 设置环境变量
    • socket – 创建UDS套接字,传递fd到启动进程。
  • trigger – 动作触发器
    匹配指定事件类型的字符串,用来触发相应动作。
    触发器可分为事件触发器(触发命令)和属性触发器(属性键值对)。
    动作可以有多个属性触发器,但只能有一个事件触发器。

// 仅启动事件触发,且属性a等于b时触发动作。
on boot && property:a=b
// 可触发三次:初始启动时,a=b且c=d时触发;a=b,当c变为d时触发;c=d,当a变为b时触发。
on property:a=b && property:c=d
  • command – 命令

    • bootchart
    • chmod
    • chown
    • class_start/stop
  • import – 导入其他rc配置文件

  • properties – 属性项,用于属性触发器
    • boot timing
      • ro.boottime.init
      • ro.boottime.init.selinux
init.rc文件分析函数

使用了Parser类分析init.rc脚本。
Parser类路径:/android/system/core/init/init_parser.cpp

  • AddSectionParser – 添加相应区域解析器
  • ParseConfig – 执行解析
    • ParseConfigDir
    • ParseConfigFile
      • read_file() – 读取文件到内存,返回字符串初始地址
        • ParseData – 解析数据
          • next_token – 返回
动作列表与服务列表的运行

ActionManager和ServiceManager

yaffs2(yet another Flash file system)
  • /
    • var
    • tmp
    • system
      • bin – shell命令
      • app – 系统应用
      • framework – java库
      • lib – bionic 标准C库
      • usr/fonts/media/etc/sounds/lost+found
    • proc
    • sys
    • sbin
    • etc
    • data
      • system/dalvik/cache/drm/logs/download/data/app/…
    • root

创建设备节点文件

udev – 用户空间设备,守护进程,获取主、次设备号等信息,供mknod命令创建设备节点,避免主次设备号发生重叠。

冷拔插

预先定义设备信息,init进程启动时统一创建设备节点文件。
系统启动完成前udev守护进程未运行。init进程按预定义的设备信息创建设备节点文件。udev的职责由init进程完成。

热拔插

系统运行过程中,有设备插入USB端口,init进程接收设备插入事件,动态创建设备节点文件。
系统运行中设备插入,内核加载设备相关驱动程序,驱动程序调用启动函数probe(),将主次设备号、设备类型保存到/sys文件系统中,然后发出uevent(用户空间事件-内核向用户空间进程传递信息的信号系统),传递给udev守护进程,udev比较uevent与/sys中的设备信息,通过后在/dev目录创建设备节点文件。

进程的终止与再启动

init的子进程意外终止时,会产生SIGCHLD传递给init进程,init接收进程后检查进程选项是否为oneshot,若是,放弃重启,否则重启进程。
大部分init启动的进程意外终止时,需要重启。

init启动的主要进程有:

  • sh – shell程序
  • adbd – ADB守护进程
  • servicemanager – 服务管理器
  • vold(Volume Dameon) – 挂载/管理USB存储或SD卡设备
  • playmp3 – 输出启动声音

属性服务

系统提供ashmen(Android Shared Memory)区域存储系统运行时所需的属性值,供所有进程共享。
属性区域由1024字节的属性域头和247块128字节的属性块组成。
属性块由32字节的name、4字节的系列号和92字节的值构成。
只有init进程才能修改属性值。因此其他进程需要修改属性,大概流程为:

  • 向init进程发出请求
  • init进程检查访问权限
  • init进程修改属性值
  • 满足条件的属性触发器被触发

JNI与NDK

安卓与JNI

使用JNI的场景:

  • 注重处理速度
  • 硬件控制
  • 复用C/C++代码

注册JNI本地函数

调用SystemloadLibrary()方法时,Java虚拟机会加载其参数指定的共享库,然后Java虚拟机检索共享库内的函数符号,检查JNI_OnLoad()函数是否实现,若实现则JNI_OnLoad()函数被自动调用,否则Java虚拟机将自动匹配本地方法和库内JNI本地函数符号。
手动映射本地方法与JNI本地函数时,需在JNI_OnLoad()函数内调用RegisterNatives()函数进行映射匹配。

Zygote

简介

Zygote通过COW(Copy on Write)方式对运行在内存中的进程实现最大程序的复用,通过库共享降低内存的使用量。
Zygote启动后,初始并运行Dalvik虚拟机,预加载需要的类和资源到内存。启动应用程序时,fork()创建出Zygote子进程,Zygote子进程动态加载并运行应用程序。

COW – 针对内存复制的一种技术。复制内存的开销非常大,创建子进程在引用父进程的内存空间时,先不复制,直接共享父进程的内存空间。当需要修改共享内存中的信息时,子进程才将父进程中相关的内存信息复制到自身的内存空间,再进行修改。

由app_process运行ZygoteInit class

Zygote由Java编写而成,不能由init进程启动运行,需先生成Dalvik虚拟机,再在Dalvik虚拟机上装载运行ZygoteInit类,这一类型任务由app_process进程完成。

  • init进程启动app_process服务
  • app_process进程创建Dalvik虚拟机
    • 生成AppRuntime对象 – AndroidRuntime类
    • 调用AppRuntime对象
    • 生成Dalvik虚拟机
  • Dalvik虚拟机初始化Zygote
    • 调用ZygoteInit类

ZygoteInit类的功能

  • 绑定套接字,接收新Android应用程序运行请求
  • 加载Android Application Framework使用的类和资源
  • 启动运行SystemServer
    • startSystemServer
      • init1 – 启动本地服务
      • init2 – 启动Android framework主要服务
  • 处理新Android应用程序请求

Android服务概要

服务的种类

  • 系统服务 – Framework提供
    • Java系统服务
      • 核心平台服务
      • 硬件服务
    • 本地系统服务
  • 应用程序服务 – 继承Service类
    • 本地服务
    • 远程服务

应用程序服务

后台服务程序,无UI界面,定期执行某些任务。

服务运行方式
  • 服务启动与终止 – onStartCommand
  • 服务绑定 – onBind/onUnbind
服务分类
本地

使用LocalBinder作为通信通道。

交互流程:

  • activity.bindService()
  • service.onBind() – LocalBinder子类
  • activity.onServiceConnected()
  • localBinder.getService() – Service对象
远程

由于应用程序在各自沙箱中运行,故需要通过IPC机制进行应用进程间通信。
用户定义AIDL,aidl工具自动生成实现类及内部类Stub,Stub.Proxy。

交互流程:

  • activity.bindService()
  • service.onBind() – IInteface.Stub.Proxy(AIDL的生成类)
  • activity.onServiceConnected()
  • IInteface.Stub.onTransact()

系统服务

本地系统服务

用C++编写,运行在Libraries层。

  • Audio Flinger
    • 耳机设备
    • 话筒设备设备
    • 蓝牙设备
  • Surface Flinger
    • Frame Buffer设备
Java系统服务

由SystemServer进程启动,分为核心平台服务与硬件服务。

核心平台服务

不直接与Android应用程序交互,android framework运行必须的服务。

  • Activity Manager Service
  • Window Manager Service – 将要绘制的内容传递给Surface Flinger
  • Package Manager Service
硬件服务

用于控制底层硬件。

  • Alarm Manager Service
  • Connectivity Service
  • Location Service
  • Power Service
  • Sensor Service
  • Telephony Service
  • Wifi Service

运行系统服务

系统服务由系统启动,使用时,直接调用getSystemService获取服务。

Media Server

负责启动除Surface Flinger外的本地服务。
功能:生成各服务的对象,并注册到Context Manager中。

System Server

负责启动Surface Flinger, Java系统服务。

  • SystemServer.main加载android_servers库,并调用init1方法
  • init1方法通过JNI调用system_init函数,初始化Surface Flinger,调用init2方法
  • init2方法创建ServerThread对象并启动
  • ServerThread创建Java系统服务,调用ServiceManager.addService方法注册服务到Context Manager。

Android Service Framework、Binder Driver概要

foo()方法调用流程:

  • 服务客户端调用foo()代理方法
  • RPC层生成Binder RPC数据(包含引用Foo服务的请求)
  • Binder RPC数据经过Marshalling(编组)处理,由服务框架(Service Manager)生成Binder IPC数据
  • Binder驱动传递Binder IPC数据给服务框架(Service Manager),unMarshalling(反编组)处理为Binder RPC数据
  • Service Stub的onTransact方法处理Binder RPC数据,定位请求的RPC方法
  • 使用Binder RPC数据调用foo()方法。

Android Binder IPC

Linux内存空间与Binder Driver

虚拟地址空间划分为用户空间和内核空间。
各进程拥有独立的用户空间,共享内核空间。
Binder提供IPC通信功能,支持进程间的RPC操作,使用运行在内核空间的抽象驱动程序Binder Driver。
Binder通过内核空间传递数据确保数据的可靠性,基于用户空间无法访问访问内核空间交换数据保证IPC的安全性。

Android Binder Model

Binder Driver接收来自服务客户端的Binder IPC数据,传递给服务端,从而实现进程间的通信。
IPC数据包含如下几个部分:

  • handle – 服务号
  • RPC代码 – 调用函数
  • RPC数据 – 调用函数参数
  • Binder协议 – IPC数据的处理方法
Binder IPC数据传递

Binder Driver是字符设备驱动程序。
系统调用:用户空间调用内核空间函数的接口。

应用程序通过Binder尝试RPC操作,系统调用流程:

  • open() – 获取Binder Driver的文件描述符
  • mmap() – 在内核中开辟一块区域
  • ioctl() – 将IPC数据作为参数传递给Binder Driver
    • BINDER_WRITE_READ – ioctl命令
Binder IPC抽象层
  • 服务层 – 客户端调用代理函数,服务端调用函数
  • RPC层 – 生成和分析RPC代码和数据
  • IPC层 – 编组和反编组RPC代码和数据为Binder IPC数据
  • Binder Driver层 – 传递IPC数据
Binder协议
  • BC_TRANSACTION(Binder Command) – IPC层传递给Binder Driver层

    • 通过handle查找Service Server
    • 更改协议为BR_TRANSACTION
    • 向Service Server传递IPC数据
  • BR_TRANSACTION(Binder Return) – Binder Driver层传回给IPC层

    • 分析IPC数据
    • 调用与RPC代码相应的函数
Binder寻址

Context Manager为注册的每个服务分配一个称为Handle的服务号,并提供服务的添加、检索等管理功能,Context Manager自身的Handle值设置为0。
Binder寻址,指inder Driver根据IPC数据中的Handle查找Service Server这一过程。

Android Binder Driver分析

从进程角度看服务的使用
服务注册

Context Manager: 接收IPC数据,发送IPC应答数据
Service Server: 发送IPC数据,接收IPC应答数据

进程交互:

  • Context Manager调用Binder Driver的open/mmap/ioctl函数等待IPC数据
  • Service Server调用Binder Driver的open/mmap/ioctl函数发送IPC数据
  • Context Manager接收IPC数据,完成服务注册,发送IPC应答数据
  • Service Server接收IPC应答数据,Binder IPC完成
服务检索

Context Manager: 接收IPC数据,发送IPC应答数据
Service Client: 发送IPC数据,接收IPC应答数据

进程交互:

  • Context Manager调用ioctl函数等待IPC数据
  • Service Client调用Binder Driver的open/mmap/ioctl函数发送IPC数据
  • Context Manager接收IPC数据,完成服务注册,发送IPC应答数据
  • Service Client接收IPC应答数据,Binder IPC完成
服务使用

Service Server: 接收IPC数据,发送IPC应答数据
Service Client: 发送IPC数据,接收IPC应答数据

进程交互:

  • Context Manager调用ioctl函数等待IPC数据
  • Service Client调用Binder Driver的open/mmap/ioctl函数发送IPC数据
  • Context Manager接收IPC数据,完成服务注册,发送IPC应答数据
  • Service Client接收IPC应答数据,Binder IPC完成
从Binder Driver角度看服务的使用
服务注册

Context Manager先于Service Server运行,最先使用Binder Driver。

服务检索

客户端向Context Manager请求指定服务的Handle的过程。

服务使用

客户端向Service Manager发起RPC调用。

Context Manager

对应进程为servicemanager,先于Service server和Service client运行。

main()函数大致的三部分:

  • binder_open() – 打开Binder Driver
  • binder_become_context_manager() – 注册服务号handle = 0
  • binder_loop() – 接收IPC数据

Android Service Framework

服务框架

安卓服务框架提供的主要功能:

  • 服务接口 – AIDL
  • 服务生成 – Stub, Stub.Proxy
  • Binder IPC处理
  • 服务管理 – 服务注册及检索

服务框架的构成

各层元素配置
  • 服务层
    • 客户端 – IFooService接口
    • 服务端 – FooService和IFooService接口
  • RPC层 – RPC转换与分析
    • 客户端 – BpFooService代理服务
    • 服务端 – BnFooService服务Stub
  • IPC层 – IPC传输,与RPC转换与分析
    • 客户端 – BpBinder、IPCThreadState
    • 服务端 – BBinder、IPCThreadState
各层各元素间的相互作用

同层元素相互对应、相互作用。

  • 服务层IFooService向两端提供统一的foo()接口
  • RPC层的服务代理与服务Stub支持Binder RPC操作
  • IPC层的BpBinder与BBinder支持Binder IPC操作
类的结构
  • IBinder – Android Binder类的抽象
    • BBinder – 接收RPC代码与数据,生成Binder节点
    • BpBinder – 保存目标服务的Handle
  • IInterface – 提供类型变换功能,将服务代理或服务Stub转换为IBinder类型
    • BnInterface – 转换服务类
    • BpInterface – 转换服务代理类
  • ProcessState – 管理Binder Driver
    • 拥有IPCThreadState – 支持Binder IPC通信
      • 拥有Parcel

按层划分类为:

  • 服务层:IInterface, BnInterface, BpInterface, BpRefBase, 服务接口,服务类
  • RPC层:服务代理类,服务Stub类
  • IPC层:BBinder, BpBinder, IPCThreadState, ProcessState, Parcel

运行机制

服务接口 – IAudioFlinger – 定义通信接口

继承自IInterface, 增加了asInterface、getInterfaceDescriptor方法

服务 – AudioFlinger – 实现服务功能

单例模式,instantiate方法,实现IAudioFlinger接口。

服务Stub – BnAudioFlinger – 处理服务的RPC代码与数据

继承自BnInterface,调用onTransact方法处理RPC代码与数据,该类继承IAudioFlinger和BBinder接口。
BBinder执行transact方法,处理基本的RPC代码,触发onTransact调用。

服务代理 – BpAudioFlinger

继承自BpInterface,该类继承IAudioFlinger各BpRefBase接口
BpRefBase接口继承自IBinder。

IAudioFlinger与IBinder类型转换
  • IInterface.asBinder(): IAudioFlinger → IBinder
    • BBinder(服务) – BnInterface.onAsBinder
    • BpBinder(服务代理) – BpInterface.onAsBinder
  • IAudioFlinger.asInterface(): IBinder → IAudioFlinger
    • AudioFlinger(服务)
    • BpAudioFlinger(服务代理)

本地服务管理器

  • C/C++层Service Manager – Context Manager代理
  • Java层Service Manager – C/C++层Service Manager代理

服务注册时,是ServiceManager向Context提出服务注册请求,BpServiceManager是服务代理,服务Stub是Context Manager处理,而非BnServiceManager,与普通服务不一致。

本地服务器主要成员函数:

  • getService()
  • addService()
  • checkService()
  • listService()

编写本地服务

客户端源码:frameworks/base/cmds/helloworld
服务端头文件:frameworks/base/include/helloworld
服务端源码:frameworks/base/libs/helloworld

服务接口-IHelloWorldService.h
  • 定义HelloWorldService使用的RPC代码
  • 定义服务接口宏DECLARE_META_INTERFACE
  • 定义服务函数
服务Stub-BnHelloWorldService.h
  • 继承BnInterface接口
  • 重定义BBinder类的onTransact方法
    • 增加HelloWorldService使用的RPC代码判断
    • 检查接口
    • 读取RPC数据
    • 调用服务函数
服务-HelloWorldService.h
  • 实现服务接口宏IMPLEMENT_META_INTERFACE – 实现类
  • 继承BnHelloWorldService
  • 实现服务函数
  • 私有化构造函数,增加instantiate方法
    • 服务注册
服务代理-BpHelloWorldService.h
  • 继承BpInterface接口
  • 实现服务函数代理
    • 将服务接口名称保存到数据中
    • 将服务函数参数保存到数据中
    • 调用BpBinder类的transact方法
    • 读取服务函数调用返回结果
服务开启-main_helloworldservice.cpp
  • main方法
    • 实例化HelloWorldService
    • ProcessState创建线程池
    • ProcessState加入线程池
服务调用-main_helloworldclient.cpp
  • main方法
    • 获取Service Manager代理
    • 检索服务 – 因为不确定服务开启时间,要做等待判断
    • 接口转换
    • 调用服务代理函数

本地系统服务分析

相机服务

本地系统服务之一
兼容性定义文档:CDD(Compatibility Definition Document)
兼容性测试套件:CTS(Compatibility Test Suit)

相机应用程序

  • 权限 – android.permission.CAMERA
  • 预览界面 – Preview
    • 继承自SurfaceView
    • 实现SurfaceHolder.Callback接口
      • surfaceCreated() – camera.open
      • surfaceChanged() – camera.setParameters/startPreview
      • surfaceDestoryed() – camera.stopPreview/release

相机服务框架

层次结构
应用框架层
  • android.view.SurfaceView
  • android.hardware.Camera
  • android.media.MediaRecorder
本地库
  • SurfaceFlinger
  • Camera – android.hardware.Camera通过JNI调用
  • CameraService – Camera服务连接
  • CameraHardwareInterface – 定义服务框架层访问相机设备接口
  • Special Camera –相机实现
  • MediaRecorder – 与Camera交互
  • V4L2 – 视频截取实现
内核
  • Frame buffer Driver
  • Special Camera Driver
  • V4L2 Kernel Driver
框架类
服务接口
  • ICameraService – 应用程序与相机服务间的连接
  • ICamera – 相机设备的设置、控制
  • ICameraClient – 相机设备的事件处理
服务Stub
  • BnCameraService
  • BnCamera
  • BnCameraClient
服务
  • CameraService – 继承BnCameraService
    • 创建BpCameraClient实例
    • 创建CameraService::Client实例
  • CameraService::Client – 继承BnCamera
    • 创建CameraHardwareInterface实例
    • 持有BpCameraClient实例
  • Camera – 继承BnCameraClient
    • android.hardware.Camera的JNI调用对象
    • 创建BpCameraService实例
    • 创建BpCamera实例
服务代理
  • BpCameraService
  • BpCamera
  • BpCameraClient

相机服务框架的运行

服务启动

相机服务在Media Server中初始化。Media Server是初始化大部分本地系统服务的Service Server。

  • 初始化CameraService
  • 注册到Context Manager
相机连接
  • android.hardware.Camera.open()
  • Camera.connect()
    • 创建Camera实例
    • 检索CameraService的Handle服务号,获取BpCameraService实例
    • 调用BpCameraService的connect方法
      • BnCameraService::onTransact方法
        • 转换为BpCameraClient实例
        • 调用CameraService::connect方法,获得BpCamera实例
          • 创建CameraService::Client对象,调用Client构造函数
            • 保存CameraService实例
            • 保存BpCameraClient实例对象
            • openCameraHardware初始化设备
          • 保存并返回BpCamera实例
        • 返回BpCamera实例
    • 返回Camera实例
相机设置与控制
  • android.hardware.Camera.setParameters()
    • Camera.setParameters()
      • BpCamera调用setParameters()
        • BnCamera.onTransact()
          • CameraService::Client::setParameters()
            • CameraHardwareInterface的setParameters()
相机事件处理

Shutter事件产生后,事件处理过程:

  • CameraHardwareInterface触发Shutter事件
    • 回调CameraService::Client的handleShutter()函数
      • BpCameraClient调用notifyCallback传递Shutter事件
        • BnCameraClient调用Camera::notifyCallback处理消息
          • 调用CameraListener的notify转发Shutter事件给应用程序
      • CameraHardwareInterface关闭Shutter消息类型

Java服务框架

简介

与本地服务框架的不同点:
  • 服务生成
    • 继承Binder类,AIDL定义服务接口,aidl工具根据AIDL生成服务类、服务Stub和服务代理
    • 继承Service类,适用于周期性的后台任务
  • Binder IPC的处理
    • Java服务框架通过JNI使用本地服务框架中的相应组成部分
  • Java服务管理
    • 与本地系统服务一致,注册到Context Manager
    • 由Activity Manager Service管理
框架的层次结构
服务层

由于框架层的ServiceManager是非公开的,因此开发时无法使用ServiceManager直接检索服务,故提供了服务代理包装类FooManager,由ContextImpl.getSystemService()获取,其方法内部实际是通过ServiceManager检索服务,获取服务代理,保存在创建FooManager类中。
IFooService由aidl工具根据AIDL自动生成。

  • 客户端:IFooService, FooManager
  • 服务端:IFooService, FooService
RPC层

aidl工具自动生成服务代理和服务Stub。

  • 客户端:IFooService.Stub.Proxy
  • 服务端:IFooService.Stub
IPC层

本地服务框架使用BpBinder和BBinder来支持Binder IPC。Java服务框架使用JNI方式调用本地服务框架类来实现Binder IPC支持。

  • 客户端:BinderProxy

    • BinderProxy.transact() → BpBinder.transact()
  • 服务端:Binder

    • JavaBBinder.transact() → Binder.execTransact()
    • JavaBBinder继承BBinder类,实现Binder.execTransact()调用

框架初始化

app_process进程启动时,AndroidRuntime类调用startReg()函数,加载JNI函数到虚拟机。
register_android_os_Binder()函数注册Java服务框架有关的本地函数。

  • register_android_os_Binder()
  • register_android_os_BinderInternal()
  • register_android_os_BinderProxy()
  • register_android_os_Parcel()

Java系统服务的实现

以闹钟服务为例。

服务接口-IAlarmManager

继承自IInterface(Java)类,aidl自动生成。

服务Stub-AlarmManagerService.Stub

继承IAlarmManager和Binder类,aidl自动生成。
重写Binder类的onTransact()方法,实现闹钟服务的RPC处理功能。
类似于本地服务框架中的BnAlarmManagerService。

服务-AlarmManagerService

继承服务Stub,实现服务接口具体功能。

服务代理-AlarmManagerService.Stub.Proxy

继承IAlarmManager和Binder类,aidl自动生成。
类似于本地服务框架中的BpAlarmManagerService。

服务代理包装类-AlarmManager

Service Manager(Java)包装类,实现服务检索。
ContextImpl.getAlarmManager()方法获取服务代理,返回服务代理包装类。

本地服务框架连接类-BinderInternal

BinderInternal为静态类,提供获取BpBinder对象的功能,BpBinder对象指向Context Manager。
getContextObject()获取BpBinder对象。
实际也是通过ProcessState的getContextObject()函数获取BpBinder对象,调用javaObjectForIBinder()生成BinderProxy对象。

Java Service Manager运行

服务注册
  • SystemServer的ServerThread创建并注册AlarmManagerService
    • ServiceManager.addService()
      • getIServiceManager().addService()
        • ServiceManagerNative.asInterface()
          • 参数为BinderInternal.getContextObject()
          • IServiceManager.queryLocalInterface()
          • 创建并返回ServiceManagerProxy()
服务检索与使用
  • ContextImpl.getSystemService()
    • ServiceManager.getService()
      • IBinder对象的缓存中检索服务
      • getIServiceManager().getService()
    • IAlarmManager.Stub.asInterface
    • 生成并返回AlarmManager

使用AIDL生成服务代理与服务Stub

使用AIDL实现IPC服务的步骤:

  • 使用AIDL语法定义服务接口
  • 在frameworks/base/Android.mk的LOCAL_SRC_FILES中添加aidl文件
  • 继承Stub类,实现具体的服务接口方法
  • 在SystemServer中的ServerThread的run方法中创建并注册服务
  • 创建服务代理包装类,在ContextImpl.getSystemService中添加条件判断
  • 在ContextImpl中编写获取服务代理包装类的方法
  • 调用make update-api命令更新frameworks/base/api/current.xml文件,公开服务代理包装类
AIDL语法
支持的数据类型
  • Java基本类型,String,CharSequence、AIDL生成的接口类型或Parcelable类型
  • List, Map容器类型,元素必须上面支持的数据类型
声明
  • interface
  • oneway interface – 不需应答,直接调用返回
类型控制
  • in – 强制输入类型
  • out – 强制输出类型
  • inout – 强制输出输出类型

Java系统服务运行分析

Activity Manager Service

生成Android应用程序Activity和服务,管理它们的生命周期。

Remote Service生成过程:

  • activity.start/bindService()
  • Activity Manager Service向Zygote请求生成用于运行服务的ActivityThread
  • Zygote接收请求后,创建新进程,加载ActivityThread
  • ActivityThread启动RemoteService服务

Activity Manager Service创建服务分析

startService请求生成ActivityThread过程:

  • activity.startService()
    • ContextWrapper类,实际是ContextImpl的startService方法
  • ActivityManagerProxy发起startService调用请求
    • ActivityManagerNative.getDefault()获取ActivityManagerProxy对象
  • ActivityManagerNative处理startService调用请求
    • 获取ApplicationThreadProxy对象作为参数
  • ActivityManagerService调用startService()
    • startServiceLocked()
      • retrieveServiceLocked()返回ServiceLookupResult
      • serviceLookupResult.record取得ServiceRecord对象
      • bringUpServiceLocked()
        • getProcessRecordLocked()返回ProcessRecord
        • 无需生成Process: realStartServiceLocked(),调用返回
        • 要生成:startProcessLocked(), pendingServices.add()
          • 创建ProcessRecordLocked()
          • processNames记录进程名、应用uid、ProcessRecord
          • startProcessLocked()
            • packageManager.getPackageGids()
            • Process.start()
            • pidsSelfLocked存储pid和ProcessRecord的对应关系

ActivityThread启动过程:
Zygote会接收运行指定类的请求,创建新进程,加载指定类到进程中,调用类的main()方法。

  • 消息队列
    • Looper.prepareMainLooper() – 生成
    • Looper.loop() – 运行
  • ActivityThread对象
    • 创建ActivityThread对象
    • 调用attach()方法
      • ActivityManagerProxy.attachApplication()
        • ActivityManagerNative.getDefault()取得服务代理对象
      • ActivityManagerNative.attachApplication()
      • ActivityManagerService.attachApplication()
        • attachApplicationLocked()
          • pidsSelfLocked获取pid对应的ProcessRecord
          • 连接ProcessRecord和IApplicationThreadProxy对象
          • 移除pendingService中对象
          • realStartServiceLocked完成服务启动

Service启动过程:

  • ActivityManagerService.realStartServiceLocked启动服务
    • ApplicationThreadProxy.scheduleCreateService()
    • ApplicationThreadNative.scheduleCreateService()
    • ApplicationThread.scheduleCreateService()
      • 创建CreateServiceData()保存IBinder和服务信息
      • queueOrSendMessage()
        • ativityThread.handleCreateService()
          • getPackageInfoNoCheck()
          • packageInfo.getClassLoader()
          • classLoader.newInstance()
          • service.onCreate()

服务接口:

  • IActivityManager – 控制组件运行、管理Activity生命周期
    • ActivityManagerProxy
    • ActivityManagerNative
  • IApplicationThread – 与ActivityThread位于同一进程,接收AMS控制命令,实际控制操作由ActivityThread完成
    • activityThread.getApplicationThread()

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/82117905