性能优化专项聊完,进入Framework专项。资深/架构师岗Framework必考,腾讯微信团队做系统级优化对Framework理解要求高。AMS原理、Zygote fork流程、Binder机制——每个话题能聊半小时,靠突击背题过不了。今天8道题覆盖四大核心方向。
Q1:Android系统启动流程?从按下电源到桌面显示经历了什么?
完整链路分四个阶段:
Bootloader→内核→init:硬件初始化→加载内核→init进程(PID 1)解析init.rc启动系统服务和Zygote。
Zygote:Java世界起点。启动app_process,初始化ART虚拟机,预加载系统类和资源(约8000个类),创建ServerSocket等待fork请求。
SystemServer:Zygote fork的第一个Java进程。启动AMS/PMS/WMS等核心服务,启动Launcher显示桌面。
追问:为什么要预加载类?ART虚拟机加载类要几百毫秒。Zygote启动时把常用类(约8000个)加载到内存,fork后子进程通过写时复制共享这些类,每个App省了几百毫秒启动时间。
Q2:Zygote的fork机制?写时复制(COW)怎么工作?
Zygote是所有App进程的父进程。App启动时不是从零创建进程——AMS给Zygote发消息,Zygote fork一个子进程,子进程继承Zygote的虚拟机、已加载的类和资源。
写时复制(Copy On Write):fork后父子进程共享物理内存页。只有当某一方修改某个内存页时,系统才复制该页。所以Zygote预加载的8000个类在内存中只有一份——所有App进程共享。
为什么不用多线程而用多进程:进程隔离更安全——一个App崩溃不影响其他App。内存独立管理,OOM只杀自己的进程。安全性——进程间不能直接访问对方内存。
追问:Zygote为什么用Socket不用Binder?Zygote启动时Binder还没初始化(SystemServer还没起来),但Zygote需要接收fork请求。Socket比Binder初始化简单,在init.rc里就能启动。
Q3:SystemServer启动流程?核心服务怎么初始化的?
SystemServer是Zygote fork的第一个Java进程,负责启动所有核心系统服务。
启动顺序:main() → run() → 初始化Looper → 创建SystemServiceManager → 启动引导服务(Installer等) → 启动核心服务(AMS、PMS、PowerManager) → 启动其他服务(WMS、NotificationManager、InputManager) → AMS.systemReady()启动Launcher。
追问:AMS和WMS谁先启动?AMS先。因为WMS需要AMS提供的窗口Token和Activity信息。启动顺序有严格依赖——PMS在AMS之前(AMS需要查APK信息),WMS在AMS之后。
Q4:AMS怎么管理四大组件?ActivityRecord是什么?
**AMS(ActivityManagerService)**是Android四大组件的总管家。
Activity管理:每个Activity对应ActivityRecord,记录状态、所在Task、进程信息。Task(TaskRecord)管理一组ActivityRecord。AMS通过这些结构维护Activity生命周期。
Service管理:ServiceRecord记录状态。startService时AMS确保Service进程存活,调onCreate/onStartCommand。bindService维护连接关系。
BroadcastReceiver管理:BroadcastQueue分发广播。有序按priority排序,无序同时派发。动态注册在AMS的mRegisteredReceivers里,静态的通过PMS扫描Manifest获取。
追问:ContentProvider怎么启动的?应用进程启动后AMS调installContentProviders——扫描Manifest里的provider标签,通过ClassLoader加载Provider类并调onCreate。Provider跨进程访问通过ContentProviderProxy/ContentProviderNative(Binder机制)。
Q5:进程管理?OOM_adj优先级怎么工作的?
Android用OOM_adj值决定杀进程顺序(值越大越先被杀):
前台进程(前台Activity、交互中Service):adj=0,几乎不杀。可见进程(可见非前台):adj=1。感知进程(前台Service如音乐):adj=2。服务进程(后台Service):adj=3-4。缓存进程(无活跃组件):adj=5-15。
杀进程时机:lowmemorykiller触发,从adj最高的开始杀。
追问:怎么提高进程优先级?startForeground让Service变成前台服务(adj=0级)。但Android 8.0后后台Service限制增多,长时间任务必须用前台服务+通知。JobIntentService也是方案——系统在合适时机调度执行。
Q6:Binder通信原理?为什么比Intent/Socket快?
Binder是Android的IPC核心机制。一次数据拷贝——发送方把数据copy到内核空间的内核缓冲区,接收方的用户空间映射到同一块内核缓冲区(mmap),所以接收方直接读到数据不需要再copy。
对比:Socket两次拷贝(发送方→内核→接收方),管道两次拷贝,共享内存零拷贝但需要自己管理同步。Binder在安全性和易用性上优于共享内存。
架构:Client → Binder Driver(内核) → ServiceManager(查找服务) → Server。Client通过Binder Proxy调Server的Binder Stub,Driver在内核层做数据拷贝和线程调度。
追问:Binder线程池默认几个?16个(可以通过Binder.setMaxThreads调)。Binder调用超时会怎样?默认10秒超时,超时会抛TransactionTooLargeException或ANR(如果在主线程调)。
Q7:PMS安装APK的完整流程?
安装步骤:
- 拷贝APK到/data/app/
- 解析APK:解析AndroidManifest提取包名、版本、权限、组件、签名
- 签名校验:v2/v3签名验证APK完整性
- dex优化:ART编译dex为oat(AOT)或保存做JIT优化
- 分配UID:同签名同UID可共享数据
- 注册到PMS:Package信息入内存+写入packages.xml持久化
- 发送广播:PACKAGE_ADDED通知其他App
Q8:Android 10+的分区存储(Scoped Storage)对App影响?
变化:App不再能随意访问外部存储的所有文件。每个App有自己的沙盒目录(/storage/emulated/0/Android/data/包名/),访问其他目录需要MediaStore API或Storage Access Framework。
影响:文件管理器App需要MANAGE_EXTERNAL_STORAGE权限(Google Play审核严格)。图片访问改用MediaStore.Images查询。下载文件用DownloadManager或ACTION_CREATE_DOCUMENT。
为什么改:隐私保护——防止App随意读取用户照片/文件,恶意App不能扫描全盘找敏感文件。
面试Tips:Framework靠积累不靠突击。Zygote启动流程必考(预加载+fork+COW三件套),Binder原理必考(一次拷贝+mmap),进程管理adj值必考。能画流程图比说十分钟强。推荐Gityuan博客和cs.android.com在线看源码。
下一篇进入腾讯Compose专项面经,Jetpack Compose的状态管理、重组机制、自定义Layout——声明式UI的底层原理。
读过Android源码的同学评论区报到,你看过最深的模块是哪个?
本系列连载中,关注不迷路,下一篇:腾讯高级Android(Compose专项)面试真题
系列简介:Android大厂面经连载,覆盖字节跳动、腾讯、阿里、美团等40+企业,从初级到架构师全岗位覆盖。每篇文章包含真实面试题+详细答案+代码示例,帮你拿到大厂Offer。