[汇总]Android Framework相关

一、Framework组件

1、说说你对Context的理解?

Context是一个抽象类,代表上下文环境

  • Application Context

全局单例,适合:全局单例、工具类、长时间持有 Context

  • Service Context

生命周期同 Service,不能弹 Dialog、不能操作 View

  • Activity Context

有界面、有 Theme、可以弹 Dialog、可以操作 UI,但不能长时间持有,容易内存泄漏

2、ActivityThread工作原理?

一句话:

ActivityThread 就是应用进程的主线程管理类,它掌管 Looper、接收 AMS 指令、调度四大组件生命周期、处理所有 UI 事件。

你可以把它理解成:

App 进程的入口主类 + 主线程管家。

事件流程:AMS → Binder → ApplicationThread → mH Handler → ActivityThread.handleXX → 组件生命周期

复制代码
final H mH = new H();

的查看方式参考android Framework

4、简单说下Android系统架构

Linux 内核:驱动、进程、内存、Binder

系统库 & ART:虚拟机、各种底层库(SQLite、OpenGL、Webkit、媒体库等)

Framework:四大组件、系统服务(AMS/PMS/WMS)

应用层:系统应用 + 第三方 App

AMS ------ ActivityManagerService

PMS ------ PackageManagerService

WMS ------ WindowManagerService

5、JVM、Art、Dalvik的区别、比较

JVM (Java Virtual Machine)

  • 官方 Java 虚拟机,运行 Java/Kotlin 字节码(.class)
  • 设计目标:跨平台、一次编译到处运行
  • 适用:服务器、桌面、嵌入式(非 Android)

Dalvik (DVM)

  • Google 为 Android 1.0--4.4 定制的虚拟机
  • 针对 移动设备内存 / CPU 受限 优化
  • 已废弃:Android 5.0 起被 ART 取代

ART (Android Runtime)

  • Android 5.0+ 默认运行时,完全替代 Dalvik
  • 核心改进:AOT 预编译 + 混合编译 + 全新 GC
  • 目标:性能、流畅度、省电

二、view绘制

1、Requestlayout,onlayout,onDraw,DrawChild区别与联系?

  1. requestLayout 会触发 onMeasure + onLayout,可能触发 draw
  2. onLayout 是布局阶段,只摆位置
  3. onDraw 画自己
  4. drawChild 画孩子,由父 View 在 dispatchDraw 中调用

整体流程:

requestLayout → measure → layout → draw

onLayout 摆位置 → onDraw 画自己 → drawChild 画孩子

2、LinearLayout的onLayout方法实现解析(layoutVertical核心源码)

LinearLayout 垂直 layout 原理:

  1. 根据父 gravity 算起始 top

  2. 循环子 View,从上往下依次排列

  3. 每个子 View 位置:

    • left 由 layout_gravity 决定
    • top 是上一个底部位置
  4. 不断累加高度,形成垂直排列

3、View的绘制流程?

Android View 绘制流程分为三大步骤:

  1. onMeasure:自上而下递归测量所有 View 的宽高
  2. onLayout:父容器确定子 View 的位置
  3. onDraw:按照 "背景→自身→子 View→前景" 的顺序绘制到屏幕

requestLayout()

触发:measure + layout

不保证 draw

invalidate()

触发:draw

只重绘,不重新布局

postInvalidate()

子线程调用 invalidate

三、事件分发

安卓层级:Activity -> Window -> 根ViewGroup -> 子ViewGroup -> 子View

1、如何解决View的事件冲突?举个开发中遇到的例子?

内部拦截法

子 View 在 dispatchTouchEvent 中调用

java 复制代码
getParent().requestDisallowInterceptTouchEvent(true/false);

告诉父容器:要不要拦截事件

外部拦截法

父 View 重写 onInterceptTouchEvent

根据条件自己决定:是否拦截事件

三、ipc通信

1、Binder框架中ServiceManager的作用?

ServiceManager 是 Binder 机制的服务管理中心

  • 维护系统服务的名称与 Binder 引用映射表
  • 提供注册服务查询服务功能
  • 是 Binder 通信的DNS 服务器
  • 句柄固定为 0,是整个 Binder 架构的基础

2、为什么选择Binder?Binder机制的作用和原理?

Binder 驱动在内核空间开辟一块共享区域,通过 mmap 实现一次内存拷贝,把跨进程调用伪装成本地方法调用

共享内存性能最强但不安全、难用

Socket 通用但性能弱、无身份校验

管道 / 消息队列效率低、结构不适合 RPC

Binder 兼具:

  • 一次拷贝高性能
  • 内核 UID 安全校验
  • C/S 架构适合 RPC
  • 易用稳定,面向对象

3、讲讲AIDL?如何优化多模块都使用AIDL的情况?

AIDL = Android Interface Definition Language

安卓接口定义语言,用来快速生成 Binder 通信代码的工具。

本质就是:定义接口 → 自动生成 Proxy/Stub 代码,不用手写 Binder。

多模块 AIDL 优化思路

  1. 独立公共 AIDL 模块,统一维护接口
  2. 统一单个 IPC Service + 路由分发
  3. 合并请求,减少 IPC 次数
  4. 使用 oneway 异步调用
  5. 统一数据结构,减少序列化开销
  6. 统一死亡回调,避免内存泄漏
  7. 增加版本号兼容

4、Android中IPC方式、各种方式优缺点?为何需要IPC?多进程通信可能会出现的问题?

方式 性能 优点 缺点
Binder/AIDL 安全、易用、RPC 略复杂
Intent/ Bundle 最简单 功能弱
文件共享 简单 不安全、不实时
Messenger 简单易用 串行、功能弱
ContentProvider 安全、系统级 较重
Socket 跨平台 开销大
共享内存 极高 最快 复杂、不安全

为何需要 IPC

内存隔离、功能隔离、系统通信、多 App 数据共享、申请更多内存。

多进程问题

静态变量失效、线程同步失效、SP 不可靠、Application 多次初始化、数据库不安全、内存增加。

4、AIDL理解

AIDL(Android Interface Definition Language):Android中用于定义进程间通信接口的一种语言(基于 Binder 的)。

饿了么HermesEventBus跨进程通信,本质也是AIDL通信

AIDL: 每一个进程都有自己的Dalvik VM实例,都有自己的一块独立的内存,都在自己的内存上存储自己的数据,执行着自己的操作,都在自己的那片狭小的空间里过完自己的一生。而aidl就类似与两个进程之间的桥梁,使得两个进程之间可以进行数据的传输,跨进程通信有多种选择,比如 BroadcastReceiver , Messenger 等,但是 BroadcastReceiver 占用的系统资源比较多,如果是频繁的跨进程通信的话显然是不可取的;Messenger 进行跨进程通信时请求队列是同步进行的,无法并发执行。

5、Binder机制原理

Binder是Android中进程间通信的核心机制,它通过驱动层和框架层的配合实现进程间通信。Binder的工作原理如下:

  1. 服务端注册Binder对象:服务端通过Binder机制创建一个Binder对象,并将其注册到ServiceManager中,以便客户端可以通过Binder对象的引用来访问服务端。
  2. 客户端获取Binder对象:客户端通过ServiceManager获取服务端注册的Binder对象的引用。
  3. 客户端与服务端通信:客户端通过Binder对象的引用调用服务端提供的方法,实现进程间通信。
  4. 跨进程通信:Binder在内核层通过驱动进行跨进程通信,具体实现是通过进程间共享内存和进程间信号量来完成的。当客户端调用服务端的方法时,Binder会将客户端的请求封装成一个数据结构,然后通过驱动将数据发送给服务端。服务端接收到请求后,再将处理结果返回给客户端。
  5. Binder对象的引用计数:Binder对象的引用计数机制可以确保在没有客户端使用时,服务端可以被回收。当没有客户端使用时,Binder对象会调用其onLastStrongRef()方法,然后被销毁。

IPC 机制:进程间通信机制

Binder机制是Android系统中的一个重要的进程间通信(IPC)机制。以下是一些与Binder机制相关的面试知识点:

  1. Binder的基本原理:Binder机制基于C/S架构,使用了驱动层、服务管理器、Binder驱动和Binder对象等组件来实现进程间通信。

  2. Binder的角色:在Binder机制中,有三种主要角色:客户端、服务端和Binder驱动。客户端通过代理对象与服务端进行通信,而Binder驱动负责处理进程间的数据传输和通信。

  3. Binder对象:在Binder机制中,进程间通信是通过Binder对象进行的。每个Binder对象都有一个唯一的标识符(Binder引用),用于在不同进程之间进行通信。

  4. 进程间通信的方式:Binder机制提供了多种进程间通信的方式,包括跨进程方法调用、跨进程数据传输和跨进程事件通知等。

  5. AIDL(Android Interface Definition Language):AIDL是一种用于定义客户端和服务端之间接口的语言,它可以帮助开发者生成跨进程通信所需的代码。

  6. 进程间通信的安全性:Binder机制通过权限验证和用户ID(UID)来确保进程间通信的安全性,防止未授权的访问和恶意行为。

  7. Binder的性能优化:在使用Binder机制时,可以通过减少跨进程调用次数、使用轻量级数据传输方式和优化服务端代码等方式来提高性能。

6、linux的共享内存有几次拷贝,为啥android不使用linux的IPC机制

Linux 中的共享内存在使用时通常涉及两次拷贝。首先,数据从用户空间被拷贝到内核空间,然后再从内核空间拷贝到另一个进程的用户空间。

Android 之所以不直接使用 Linux 的共享内存,是因为 Android 使用了基于 Binder 的进程间通信机制。Binder 通过将数据序列化为跨进程的消息进行传递,避免了额外的内核空间拷贝。这种设计可以提供更高效的进程间通信,并且具有更好的安全性和稳定性。

此外,Android 还提供了其他的共享内存机制,如 Ashmem(匿名共享内存),用于实现特定的共享内存需求,但它并不是 Android 应用程序常用的进程间通信方式。

四、启动流程

1、大体说下一个应用程序安装到手机上时发生了什么?

应用安装时,系统会先将 APK 复制到系统目录,校验签名合法性,解析AndroidManifest文件获取四大组件与权限,为应用创建独立数据目录与 UID,对 dex 进行 dex2oat 优化,最后将应用信息注册到 PackageManagerService 并生成桌面图标,完成安装。

1、dex2oat优化:

系统对 APK 里的 dex 文件做编译优化

  • 生成 oat 可执行文件
  • 放入 /data/dalvik-cache/
  • 让后续运行更快

安装慢,大多时间都耗在这里。

2、UID

它是 Android 系统给应用分配的 Linux 用户 ID ,用来做权限隔离、沙盒控制

系统级应用分身 / 工作空间

比如微信双开:

  • 原始微信:包名 com.tencent.mm,UID = 10123
  • 分身微信:包名 仍然是 com.tencent.mm ,UID = 10188
  1. 应用分身一定是新 UID 吗?

分两种:

① 系统双开(小米、华为、OPPO 双开)

  • 系统级支持
  • 新 UID、新数据目录、独立运行
  • 安全、稳定,系统层面完全隔离

② 第三方双开 App(双开助手、平行空间等)

  • 没有系统支持
  • 共用同一个 UID
  • 自己在内部做虚拟沙盒、虚拟组件环境
  • 本质还是一个进程里跑多个逻辑应用,所以稳定性、权限都差一些

Android 权限管理的底层,就是 Linux 的 UID 用户权限机制,用于实现应用沙箱隔离;一个 Android 应用,在底层就是一个 Linux 用户(UID)。但是有2处特殊:

  • 一个应用有多个进程,它们还是同一个UID
  • 应用分身(系统双开)是 "同一个应用,多个用户"

上层再通过 PackageManagerService 扩展了相机、定位、存储等功能权限,最终所有权限检查都以 UID 为核心依据

2、进程启动顺序:

  1. Zygote fork
  2. ActivityThread.main()
  3. 初始化主线程 Looper
  4. attach 到 AMS
  5. 实例化 ContentProvider → 调用 onCreate
  6. Application 实例化 → attachBaseContext → onCreate
  7. 再启动 Activity/Service

3、Activity的冷启动流程

桌面 Launcher 发起启动请求 → 系统服务(AMS)处理

Zygote 孵化新 App 进程 → 主线程初始化 Application

AMS 调度启动目标 Activity → 主线程创建、渲染 Activity

页面可见,冷启动完成

4、Android系统启动流程是什么

1. 上电 & BootROM 启动
  • 手机按下电源键,CPU 上电
  • 执行固化在芯片里的 BootROM 代码
  • 加载并校验 BootLoader

作用:最底层硬件初始化,引导系统启动。

2. BootLoader 阶段
  • 初始化硬件(DDR、时钟、NAND/eMMC)
  • 选择启动模式(正常 / Recovery / 刷机)
  • 加载 Linux 内核(Kernel)到内存并启动

作用:系统引导程序,类似电脑的 BIOS。

3. Linux 内核启动

内核启动后做三件事:

  1. 挂载根文件系统
  2. 启动 0 号进程 idle
  3. 启动 1 号进程:init

这是 Android 世界的起点进程

4. init 进程启动(Android 世界的祖宗)

init 是用户空间的第一个进程,核心工作:

  1. 解析 init.rc 脚本

  2. 创建文件系统、挂载分区

  3. 启动系统关键守护进程:

    • servicemanager(Binder 管家)
    • surfaceflinger(显示服务)
    • vold(存储管理)
    • zygote 进程(Android 所有应用的母进程)

关键点:

init → Zygote 是整个 Android 生态的入口。

5. Zygote 进程启动(最关键)

Zygote 是所有 App 进程的父进程,作用:

  1. 预加载系统资源、系统类、主题、资源文件
  2. 创建 SystemServer 进程(fork 自己)
  3. 开启 Socket 等待孵化新 App 进程

所有 App 进程都是 Zygote fork 出来的。

6. SystemServer 进程启动

SystemServer 是系统核心服务的容器,启动:

  1. 启动 AMS(ActivityManagerService)
  2. 启动 PMS(PackageManagerService)
  3. 启动 WMS、WindowManagerService
  4. 启动其他系统服务(电池、网络、蓝牙等)

AMS、PMS、WMS 都在这里诞生。

7. 启动桌面 Launcher
  1. AMS 准备就绪后
  2. 发送 Intent 启动 HOME 类别应用
  3. 系统桌面 Launcher 启动并显示

5、四大组件启动过程

Zygote读:[ˈzaɪɡoʊt]

AMS:ActivityManagerService

Activity 启动流程(最常考)
  1. App → startActivity → Binder 调用 AMS
  2. AMS 校验权限、创建 / 查找 ActivityRecord
  3. 目标进程未启动 → AMS 让 Zygote fork 进程
  4. 进程启动 → 初始化 ActivityThread
  5. AMS 发送 SCHEDULE_LAUNCH_ACTIVITY 事务
  6. App 主线程 Handler 处理 → handleLaunchActivity
  7. 创建 Activity → 调用 onCreate → onStart → onResume
Service 启动流程
  • startService 流程
  1. App → startService → AMS
  2. AMS 检查服务是否存在
  3. 进程未启动则 fork 进程
  4. 系统通过 ApplicationThread 调用 handleCreateService
  5. 实例化 Service → onCreateonStartCommand
  • bindService 流程
  1. 同上,先创建 Service
  2. 回调 onBind
  3. 返回 Binder 给客户端,建立长连接
BroadcastReceiver 接收流程
  1. 发送广播 → AMS
  2. AMS 匹配所有静态 / 动态 Receiver
  3. 动态 Receiver:直接分发
  4. 静态 Receiver:进程未启动则 fork 进程
  5. 系统通过 handleReceiver 回调 onReceive
  6. 运行在主线程,超时 ANR
ContentProvider 启动流程
  1. 进程启动时,AMS 通知 ActivityThread
  2. Application 创建之前
  3. 系统自动实例化 ContentProvider
  4. 调用 attachInfoonCreate
  5. 之后才创建 Application
相关推荐
小红的布丁2 小时前
Reactor 模型详解:单 Reactor、主从 Reactor 与 Netty 思想
android·java·开发语言
cch89182 小时前
Laravel与ThinkPHP5.x核心对比
android
酿情师3 小时前
PHP 反序列化漏洞与 POP 链详解:网络安全小白从零入门
android·web安全·php
数厘3 小时前
2.3MySQL 表结构设计:提升 SQL 查询性能的关键
android·sql·mysql
Kiri霧3 小时前
Kotlin递归
android·开发语言·kotlin
普通网友3 小时前
Android开发:使用Kotlin+协程+自定义注解+Retrofit的网络框架
android·kotlin·retrofit
常利兵3 小时前
Kotlin抽象类与接口:相爱相杀的编程“CP”
android·开发语言·kotlin
Arkerman_Liwei3 小时前
Android 新开发模式深度实践:Kotlin + 协程 + Flow+MVVM
android·开发语言·kotlin
蹦哒3 小时前
Kotlin DSL 风格编程详解
android·开发语言·kotlin