Android Framework原理,android快速开发模板

本文详细阐述了Android系统启动过程,从内核引导到Zygote、System_Server的启动,再到ActivityManagerService控制HomeActivity的启动,涉及关键技术如Zygote、Binder通信和Handler机制。

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

这个入口的函数是start_kernel函数

start_kernel函数执行到最后调用了reset_init函数进行后续的初始化

start_kernel最终启动用户空间的init程序

启动Android

当初始化内核之后,init进程负责解析init.rc配置文件, 就会启动一个相当重要的祖先进程,也就是init进程,在Linux中所有的进程都是由init进程直接或间接fork出来的

  • /system/bin/app_process_Zygote服务启动的进程名

  • –start-system-server 表明Zygote启动完成后,需要启动System_Server进程

  • socket zygote stream 666在Zygote启动时,创建一个权限为666的socket。此socket用来请求zygote创建新进程

  • socket的fd保存在名称为"ANDROID_SOCKET_zygote"的环境变量中

init进程负责创建系统中最关键的几个核心daemon(守护)进程,尤其是zygote和System_Server进程

  1. zygote进程 android启动的第一个Dalvik 虚拟机,它将负责启动Java世界的进程

  2. zygote虚拟机启动子进程system_server,同时也可以看出zygote中定义了一个Socket,绑定666端口,用于接收ActivityManagerService启动应用程序的请求

  3. System_Server进程 Binder通信的基础,它还提供了property service(属性服务),类似于windows系统的注册表服务

  4. 系统里面重要的服务都是在这个进程里面开启的,例如AMS, WindowsManager, PackageManagerService等等都是由这个System_Server fork出来的

  5. 在System_Server进程开启的时候,就会初始化ActivityManagerService 。同时,会加载本地系统的服务库,调用createSystemContext()创建系统上下文,创建ActivityThread及开启各种服务等等

  6. system_server中开启了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态

启动Home Activity

  1. 在systemReady状态,ActivityManagerService会与zygote的Socket通信,请求启动Home

  2. zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求

  3. zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home

概况

  1. 系统加电,执行bootloader。Bootloader负责初始化软件运行的最小硬件环境,最后加载内核到内存

  2. 内核加载到内存后,进入内核引导阶段,在内核引导的最后,调用start_kernel进入内核启动阶段。start_kernel最终启动用户空间的init程序

  3. init负责解析init.rc配置文件,开启系统守护进程。2个最重要的守护进程是zygote进程和serverManager进程。zygote是android启动的第一个Dalvik虚拟机,ServiceManager服务是Binder通信的基础

  4. zygote虚拟机启动子进程system_server,在system_server中启动了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态

  5. 在SystemReady状态,ActivityManagerService与zygote中的socket通信,通过zygote启动home应用,进入系统界面

  • 从步骤3开始, init启动后,上层的实现
  1. init启动的核心Daemon服务包括Android的第一个Dalvik虚拟机Zygote

  2. zygote定义一个socket,用于接受ActivityManangerService启动应用的请求

  3. zygote通过fork系统调用创建system_server进程

  4. 在system_server进程中,将会启动系统核心服务以及其他服务

  5. 系统服务启动后会注册到ServiceManager中,用于Binder通信

  6. ActivityManagerService进入systemReady状态

  7. 在systemReady状态,ActivityManangerService会与zygote的Socket通信,请求启动Home

  8. zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求

  9. zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home

Handler机制与底层实现原理


概念

Message - Message代表一个行为what或者一串动作Runnable, 每一个消息在加入消息队列时,都有明确的目标Handler

ThreadLocal - 线程本地存储区(Thread Local Storage,简称为TLS),每个线程都有自己的私有的本地存储区域,不同线程之间彼此不能访问对方的TLS区域。ThreadLocal的作用是提供线程内的局部变量TLS,这种变量在线程的生命周期内起作用,每一个线程有他自己所属的值(线程隔离)

MessageQueue (C层与Java层都有实现) - 以队列的形式对外提供插入和删除的工作, 其内部结构是以双向链表的形式存储消息的

Looper (C层与Java层都有实现) - Looper是循环的意思,它负责从消息队列中循环的取出消息然后把消息交给Handler处理

Handler - 消息的真正处理者, 具备获取消息、发送消息、处理消息、移除消息等功能

普通的线程是没有looper的,如果需要looper对象,那么必须要先调用Looper.prepare方法,而且一个线程只能有一个looper

Handler是如何完成跨线程通信的

  • Android中采用的是Linux中的管道通信

  • 关于管道,简单来说,管道就是一个文件

  • 在管道的两端,分别是两个打开文件文件描述符,这两个打开文件描述符都是对应同一个文件,其中一个是用来读的,别一个是用来写的

  • 消息队列创建时,会调用JNI函数,初始化NativeMessageQueue对象。NativeMessageQueue则会初始化Looper对象

  • Looper的作用就是,当Jav

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

a层的消息队列中没有消息时,就使Android应用程序主线程进入等待状态,而当Java层的消息队列中来了新的消息后,就唤醒Android应用程序的主线程来处理这个消息

整个消息机制流程

Handler通过sendMessage()发送Message到MessageQueue队列

Looper通过loop(),不断提取出达到触发条件的Message,并将Message交给target来处理

经过dispatchMessage()后,交回给Handler的handleMessage()来进行相应地处理

将Message加入MessageQueue时,处往管道写入字符,可以会唤醒loop线程;如果MessageQueue中没有Message,并处于Idle状态,则会执行IdelHandler接口中的方法,往往用于做一些清理性地工作

ContentProvider原理


Android绘制原理


Activity的window组成,Activity内部有个Window成员,它的实例为PhoneWindow,PhoneWindow有个内部类是DecorView,这个DecorView就是存放布局文件的,里面有TitleActionBar和我们setContentView传入进去的layout布局文件

  1. Window类时一个抽象类,提供绘制窗口的API

  2. PhoneWindow是继承Window的一个具体的类,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View

  3. DecorView继承FrameLayout,里面id=content的就是我们传入的布局视图

  4. ContentView必须是一个ViewGroup

  5. ViewGroup 开始递归执行以下逻辑进行绘制

  • measure, 递归测量view的大小。有3种测量模式
  • MeasureSpec.EXACTLY表示确定大小

  • MeasureSpec.AT_MOST表示最大大小

  • MeasureSpec.UNSPECIFIED不确定

  • layout,递归布局view的位置

  • draw,递归绘制view

  • ViewRootImpl中的代码会创建一个Canvas对象,然后调用View的draw()方法来执行具体的绘制

AsyncTask源码分析


Binder机制及底层实现


进程空间分配

  1. 进程间,用户空间的数据不可共享,所以用户空间 = 不可共享空间

  2. 进程间,内核空间的数据可共享,所以内核空间 = 可共享空间

  3. 进程内用户与内核进行交互称为系统调用

Binder跨进程通信(IPC)的原理

  1. 先通过进程间的内核空间进行数据交互

  2. 再通过进程内的用户空间&内核空间进行数据交互,从而实现进程间的用户空间的数据交互

  3. 而Binder,就是充当连接两个进程(内核空间)的通道

使用步骤:

注册服务

  • Server进程向Binder驱动发起服务注册请求

  • Binder驱动将注册请求转发给ServiceManager进程

  • ServiceManager进程添加该服务

  • 此时ServiceManager进程拥有该服务信息

获取服务

  • Client向Binder驱动发起获取服务的请求,传递要获取的服务名称(service name)

  • Binder驱动将该请求转发给ServiceManager进程

  • ServiceManager查找到Client需要的Server对应的服务信息

  • 通过Binder驱动将上述服务信息返回给Client进程

  • 此时client进程与server进程已经建立了连接

使用服务

  • Client进程将参数数据发到Server进程
  1. client 进程将需要的传送的数据放到client进程的共享内存;(当前线程被挂起)

  2. Binder驱动从client的共享内存中读取数据,并根据ServiceManager进程里面的Server信息找到对应的Server进程

  3. Binder驱动将数据copy到Server进程的共享内存里,并通知Server进程解包

  • Server进程根据Client进程要求,调用目标方法
  1. 接到Binder驱动通知后,Server进程从线程池中取出线程,进行数据解包和调用目标方法

  2. 将最终方法结果写到自己的共享内存

  • Server进程将目标方法的结果,返回给Client进程
  1. Binder驱动程序将Server进程的共享内存里面的数据(方法执行结果) copy 到client进程的共享内存

  2. 通知client进程获得返回结果(此时client进程之前被挂起的线程被重新唤醒)

Client进程、Server进程 & Service Manager 进程之间的交互 都必须通过Binder驱动(使用 open 和 ioctl文件操作函数),而非直接交互

Client进程、Server进程 & Service Manager进程属于进程空间的用户空间,不可进行进程间交互

Binder驱动 属于 进程空间的 内核空间,可进行进程间 & 进程内交互

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值