以通俗易懂的语言,结合Android源码关键片段,为您解析Native App与SurfaceFlinger建立Binder通信的全过程。我们可以把这个过程想象成“跨城快递系统”,其中SurfaceFlinger是总部,Native App是分部,Binder驱动是物流网络,而ServiceManager则是快递目录。
一、通信前的准备:搭建物流网络(Binder驱动)
就像现实中的物流需要公路、铁路一样,Binder通信需要底层基础设施——Binder驱动。这个驱动在Android内核中实现,负责:
- 维护进程间通信的“高速公路”
- 记录服务地址簿(类似快递公司的网点目录)
- 传递带有跟踪号的包裹(事务)
在SurfaceFlinger启动时,会执行以下关键操作(源码位置:frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp):
cpp
int main(int, char**) {
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
sp<IServiceManager> sm = defaultServiceManager();
// 向ServiceManager注册两个核心服务
sm->addService(String16("SurfaceFlinger"), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
// 进入消息循环
IPCThreadState::self()->joinThreadPool();
}
二、建立通信的三种方式解析
方式1:传统Binder接口(ISurfaceComposer)
这是比较底层的通信方式,就像使用物流公司的“专线运输”:
- 服务端暴露:SurfaceFlinger实现
ISurfaceComposer接口 - 客户端获取:通过
ISurfaceComposer::asInterface()获取代理 - 典型操作:
setTransactionState(更新显示状态)
方式2:AIDL接口(推荐方式)
这是现代Android推荐的方式,类似使用标准化的“快递单”:
-
AIDL定义:
frameworks/native/libs/gui/aidl/android/gui/ISurfaceComposer.aidl -
核心方法:
createDisplay()创建虚拟显示屏createDisplayEventConnection()监听VSYNC信号
-
通信优势:自动生成类型安全的代理类,支持异步调用
方式3:Legacy接口(已废弃)
类似过时的“电报通信”,仅保留用于兼容旧系统。
三、完整通信流程示例
以创建虚拟显示屏为例,演示完整通信链路:
-
服务端注册(SurfaceFlinger启动时)
- 通过
addService向ServiceManager注册服务 - 相当于在快递目录登记“Android显示中心”
- 通过
-
客户端查询(Native App)
cpp sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16("SurfaceFlingerAIDL")); sp<ISurfaceComposer> composer = interface_cast<ISurfaceComposer>(binder);- 相当于查快递目录找到“Android显示中心”的联系方式
-
方法调用(创建显示屏)
cpp sp<IBinder> displayBinder; composer->createDisplay("VirtualDisplay", false, 60.0f, &displayBinder);- 相当于发送快递单,请求创建虚拟显示屏
-
服务端处理(SurfaceFlinger进程)
- 通过
onTransact接收请求 - 验证权限(需要
android.permission.ACCESS_SURFACE_FLINGER) - 创建DisplayDevice对象
- 返回操作结果
- 通过
-
结果返回(同步/异步)
- 同步调用:直接返回显示ID
- 异步调用:通过
@OneWay注解实现
四、关键安全机制
-
权限验证:
cpp // 在SurfaceFlinger的onTransact中 if (!checkPermission(android.Manifest.permission.ACCESS_SURFACE_FLINGER)) { return PERMISSION_DENIED; } -
死亡通知:
- 客户端注册
IBinder::DeathRecipient - 服务端崩溃时自动收到通知
- 客户端注册
-
引用计数:
- Binder驱动自动管理服务生命周期
- 最后一个客户端断开时释放资源
五、调试技巧
-
查看注册服务:
bash adb shell service list | grep SurfaceFlinger -
跟踪Binder调用:
bash adb shell binder_state_dump | grep SurfaceFlinger -
调试日志:
- 启用SurfaceFlinger调试日志:
adb shell setprop debug.sf.showupdates 1 - 跟踪Binder事务:
adb shell setprop log.tag.SurfaceFlinger DEBUG
- 启用SurfaceFlinger调试日志:
六、系统演进趋势
从Android 10开始,显示系统逐步向以下方向发展:
- AIDL标准化:完全替代传统Binder接口
- 安全增强:新增
android.permission.WAKEUP_SURFACE_FLINGER权限 - 性能优化:支持Binder调用链跟踪(
atrace)
通过理解这个“跨城快递系统”的工作原理,您可以:
- 优化显示相关的Native代码性能
- 调试画面不更新、卡顿等显示问题
- 开发需要直接操作显示系统的底层功能(如VR/AR应用)