android架构(AMS)

本文详细介绍了Android系统从Loader到App的启动过程,重点解析了AMS(Activity Manager Service)的启动和其类图结构。此外,探讨了Android进程间通信的方式,特别是Binder机制与Handler在Android系统中的应用,阐述了Binder在性能、稳定性和安全性上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android架构

Android系统启动过程:Loader -> Kernel -> Native -> Framework -> App

Loader

Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设出代码开始执行,然后加载引导程序到RAM
**Boot Loader:**这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能。

Kernel

Android内核层,到这里才刚刚开始进入Android系统。
启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作。
启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。

Native

启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。init孵化用户空间的守护进程、HAL层以及开机动画等。
init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程。
init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务。
init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。

Framework

Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:

  1. 加载ZygoteInit类,注册Zygote Socket服务端套接字
  2. 加载虚拟机
  3. preloadClasses
  4. preloadResouces

System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务。
Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service,等服务。

App

Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App。
Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
所有的App进程都是由Zygote进程fork生成的。

通信方式

进程/线程之间的通信。
IPC(Inter-Process Communication, 进程间通信)Linux现有管道、消息队列、共享内存、套接字、信号量、信号这些IPC机制,Android额外还有Binder IPC机制。
Android OS中的Zygote进程的IPC采用的是Socket机制,在上层system server、media server以及上层App之间更多的是采用Binder IPC方式来完成跨进程间的通信。
Handler:对于Android上层架构中,很多时候是在同一个进程的线程之间需要相互通信,例如同一个进程的主线程与工作线程之间的通信,往往采用的Handler消息机制。
Android上层架构,则最常用的通信方式是Binder、Socket、Handler,当然也有少量其他的IPC方式,比如杀进程Process.killProcess()采用的是signal方式。

Binder

现有IPC通讯

  1. 管道:在创建时分配一个page大小的内存,缓存区大小比较有限。
  2. 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信。
  3. 共享内存:无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决。
  4. 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信。
  5. 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  6. 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等。

Binder分析

  1. 从性能的角度
    数据拷贝次数:Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。
  2. 从稳定性的角度
    Binder是基于C/S架构的 C/S 相对独立,稳定性较好。
    共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题。
  3. 从安全的角度
    传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份。传统IPC只能由用户在数据包里填入UID/PID。可靠的身份标记只有由IPC机制本身在内核中添加。传统IPC访问接入点是开放的,无法建立私有通道
  4. 从语言层面的角度
    Linux是基于C语言(面向过程的语言),而Android是基于Java语言(面向对象的语句)
    Binder恰恰也符合面向对象的思想 Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。
    Android OS中的Zygote进程的IPC采用的是Socket(套接字)机制,Android中的Kill Process采用的signal(信号)机制等等。而Binder更多则用在system_server进程与上层App层的IPC交互。

Handler

可以详见handler源码分析

系统启动

进程启动概述
init进程Linux系统中用户空间的第一个进程, Init.main
zygote进程所有App进程的父进程, ZygoteInit.main
system_server进程系统各大服务的载体
servicemanager进程binder服务的大管家, 守护进程循环运行在binder_loop
app进程通过Process.start启动App进程, ActivityThread.main

AMS

AMS启动

在system_server进程中启动
SystemServer.java #startBootstrapServices()
创建AMS实例对象,创建Andoid Runtime,ActivityThread和Context对象
setSystemProcess:注册AMS、meminfo、cpuinfo等服务到ServiceManager
installSystemProviderss,加载SettingsProvider
启动SystemUIService,再调用一系列服务的systemReady()方法
发布Binder服务

服务名类名功能
activityActivityManagerServiceAMS
procstatsProcessStatsService进程统计
meminfoMemBinder内存
gfxinfoGraphicsBinder图像信息
dbinfoDbBinder数据库
cpuinfoCpuBinderCPU
permissionPermissionController权限
processinfoProcessInfoService进程服务
usagestatsUsageStatsService应用使用情况

想要查看这些服务的信息,可通过dumpsys <服务名>命令。比如查看CPU信息命令dumpsys cpuinfo

AMS类图结构

IActivityManager
ActivityManager
ActivityManagerService
以ActivityManager的getRunningServices()函数为例

public List<RunningServiceInfo> getRunningServices(int maxNum)
            throws SecurityException {
        try {
            return getService()
                    .getServices(maxNum, 0);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

可以看到,调用被委托到了getService.getServices()。

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

实际上调用的是ActivityManagerService中的代码

  @Override
    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
        enforceNotIsolatedCaller("getServices");

        final int callingUid = Binder.getCallingUid();
        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
        final boolean allowed = mAtmInternal.isGetTasksAllowed("getServices",
                Binder.getCallingPid(), callingUid);
        synchronized (this) {
            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
                allowed, canInteractAcrossUsers);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值