当前位置: 首页 > news >正文

【底层机制】【Android】Binder架构与原理

Binder 架构与原理

一、Binder 整体架构

1. 架构组成
  • Client:服务调用方
  • Server:服务提供方
  • ServiceManager:服务管理器,Android 系统启动时初始化的特殊 Binder 服务
  • Binder 驱动:内核空间的核心组件,负责进程间通信
2. 通信模型
Client Process      Kernel Space       Server Process|                   |                   || -- IBinder.Proxy ->|                   ||                   | -- Binder Driver ->||                   |                   | -- IBinder.Stub|                   | <- Transaction ---|| <- Result --------|                   |

二、Binder 驱动核心机制

1. 内存映射(mmap)
// Binder 驱动关键数据结构
struct binder_proc {struct hlist_node proc_node;struct rb_root threads;        // 线程红黑树struct rb_root nodes;          // Binder 节点struct list_head delivered_death; // 死亡通知列表
};struct binder_thread {struct binder_proc *proc;      // 所属进程wait_queue_head_t wait;        // 等待队列struct binder_transaction *transaction_stack; // 事务栈
};

mmap 工作原理

  • 进程打开 /dev/binder 设备后调用 mmap()
  • Binder 驱动在内核空间分配缓冲区
  • 同时映射到内核空间和用户空间
  • 一次拷贝机制:数据从客户端用户空间拷贝到内核缓冲区,服务端直接读取
2. 数据传输流程
  1. Client 发送数据

    • 数据打包为 binder_transaction_data
    • 通过 ioctl(BC_TRANSACTION) 发送到驱动
    • 驱动查找目标 Binder 实体
  2. Server 接收数据

    • 服务线程通过 ioctl(BC_ENTER_LOOPER) 进入循环
    • 调用 ioctl(BINDER_WRITE_READ) 读取事务
    • 驱动唤醒等待的服务线程

三、AIDL 本质解析

1. AIDL 生成的代码结构
// 自动生成的 Binder 接口
public interface IMyService extends android.os.IInterface {// Binder 本地对象(服务端实现)public static abstract class Stub extends android.os.Binder implements IMyService {@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) {switch (code) {case INTERFACE_TRANSACTION:reply.writeString(DESCRIPTOR);return true;case TRANSACTION_doSomething:data.enforceInterface(DESCRIPTOR);int _arg0 = data.readInt();String _result = this.doSomething(_arg0);reply.writeNoException();reply.writeString(_result);return true;}return super.onTransact(code, data, reply, flags);}}// Binder 代理对象(客户端使用)private static class Proxy implements IMyService {private android.os.IBinder mRemote;@Overridepublic String doSomething(int param) {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();String _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(param);mRemote.transact(Stub.TRANSACTION_doSomething, _data, _reply, 0);_reply.readException();_result = _reply.readString();} finally {_reply.recycle();_data.recycle();}return _result;}}
}
2. AIDL 本质
  • 代码生成工具:将接口定义转换为 Binder 通信代码
  • Proxy-Stub 模式实现
    • Proxy:客户端代理,序列化参数并调用 transact()
    • Stub:服务端基类,反序列化参数并调用实际方法
  • 接口描述符机制:确保客户端和服务端接口版本一致

startActivity 的 Binder 调用全过程

一、进程内准备阶段

1. 发起调用
// Activity.java
public void startActivity(Intent intent) {// 调用 ActivityTaskManager 服务ActivityTaskManager.getService().startActivity(mMainThread.getApplicationThread(), mToken, intent, intent.resolveTypeIfNeeded(getContentResolver()),null, // resultTonull, // resultWho0,    // requestCodeFLAG_ACTIVITY_NEW_TASK,null, // optionsnull  // userId);
}

二、Binder 调用链详细流程

1. 客户端到系统进程(第一次 Binder 调用)
Client Process (App) → System Server Process (AMS)

调用路径

  • Activity.startActivity()
  • ActivityTaskManager.getService().startActivity()
  • IActivityTaskManager.Stub.Proxy.startActivity()

Binder 事务

// IActivityTaskManager.aidl 生成的 Proxy 类
public int startActivity(IApplicationThread caller, String callingPackage,Intent intent, ...) {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeStrongBinder(caller != null ? caller.asBinder() : null);data.writeString(callingPackage);intent.writeToParcel(data, 0);// ... 其他参数序列化mRemote.transact(TRANSACTION_startActivity, data, reply, 0);reply.readException();int result = reply.readInt();return result;
}
2. 系统进程处理(AMS 侧)

AMS 处理逻辑

// ActivityTaskManagerService.java
public final int startActivity(IApplicationThread caller, ...) {return getActivityStartController().obtainStarter(intent, ...).setCaller(caller).execute();
}

关键步骤

  1. 权限验证:检查调用者权限
  2. Intent 解析:解析目标 Activity 信息
  3. 进程检查:判断目标 Activity 所在进程是否已启动
  4. 栈管理:确定 Activity 应该放入哪个 Task
3. 暂停当前 Activity(第二次 Binder 调用)
System Server Process (AMS) → Client Process (App)

AMS 调用应用进程

// 通过 ApplicationThread 的 Binder 接口
app.thread.schedulePauseActivity(token, finished, userLeaving, configChanges);

应用进程处理

// ActivityThread.java - ApplicationThread 内部类
public final void schedulePauseActivity(IBinder token, ...) {sendMessage(H.PAUSE_ACTIVITY, token);
}// H(Handler)处理消息
case PAUSE_ACTIVITY: {handlePauseActivity((IBinder)msg.obj, ...);break;
}private void handlePauseActivity(IBinder token, ...) {ActivityClientRecord r = mActivities.get(token);if (r != null) {// 调用 Activity 的 onPause()performPauseActivity(r, finished, reason, pendingActions);}
}
4. 启动目标进程(如果需要)

进程创建流程

  1. AMS 通过 Process.start() 请求 Zygote
  2. Zygote fork 新进程
  3. 新进程入口:ActivityThread.main()
5. 启动目标 Activity(第三次 Binder 调用)
System Server Process (AMS) → Target Process (App)

AMS 调用目标进程

// 通过目标进程的 ApplicationThread
thread.scheduleLaunchActivity(new Intent(r.intent), ...);

目标进程处理

// ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, ...) {// 1. 创建 Activity 实例Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);// 2. 创建 Application(如果不存在)Application app = r.packageInfo.makeApplication(false, mInstrumentation);// 3. 关联 Contextactivity.attach(appContext, ...);// 4. 调用 onCreate()mInstrumentation.callActivityOnCreate(activity, r.state);// 5. 调用 onStart()activity.performStart();// 6. 调用 onResume()activity.performResume();
}

三、Window 管理相关的 Binder 调用

1. 窗口创建(第四次 Binder 调用)
Target Process (App) → WindowManagerService (WMS)

调用流程

// ActivityThread.handleResumeActivity()
final void handleResumeActivity(IBinder token, ...) {// 调用 Activity.onResume()ActivityClientRecord r = performResumeActivity(token, ...);if (r.activity.mVisibleFromClient) {// 添加窗口到 WMSViewManager wm = r.activity.getWindowManager();wm.addView(decorView, layoutParams);}
}// WindowManagerGlobal.addView()
public void addView(View view, ViewGroup.LayoutParams params, ...) {ViewRootImpl root = new ViewRootImpl(view.getContext(), display);root.setView(view, wparams, panelParentView);
}

ViewRootImpl 与 WMS 通信

// ViewRootImpl.java
public void setView(View view, ...) {// 通过 Session 与 WMS 通信res = mWindowSession.addToDisplay(mWindow, ...);
}

四、Binder 驱动中的关键数据结构

1. 事务处理
struct binder_transaction_data {union {size_t handle;    // 对 Server 的引用void *ptr;        // Server 的本地地址} target;void *data.ptr;       // 数据缓冲区size_t data_size;     // 数据大小
};// Binder 驱动处理事务
static void binder_transaction(struct binder_proc *proc,struct binder_thread *thread,struct binder_transaction_data *tr) {// 查找目标 Binder 节点target_node = binder_get_node(proc, tr->target.handle);// 分配事务缓冲区t = kzalloc(sizeof(*t), GFP_KERNEL);// 拷贝数据到目标进程t->buffer = binder_alloc_buf(target_proc, tr->data_size);
}

五、完整调用时序总结

[Client Process]           [Binder Driver]        [System Server]        [Target Process]|                           |                       |                       ||--- startActivity() ------>|                       |                       ||                           |-- TRANSACTION ------->|                       ||                           |                       |-- AMS.startActivity() ||                           |                       |                       ||                           |<-- schedulePauseActivity --|                  ||<-- onPause() ------------|                       |                       ||                           |                       |                       ||                           |                       |-- (如果需要)创建进程 -||                           |                       |                       ||                           |<-- scheduleLaunchActivity -|                  ||                           |                       |                  |-- onCreate()|                           |                       |                  |-- onStart()  |                           |                       |                  |-- onResume()|                           |                       |                  |-- addView()|                           |                       |                  |   (WMS调用)

六、性能优化关键点

  1. 一次拷贝优势:相比其他 IPC(如 Socket 需要 4 次拷贝),Binder 只需 1 次用户空间到内核空间的拷贝
  2. 引用计数:Binder 对象自动管理生命周期,避免内存泄漏
  3. 线程池管理:Binder 驱动维护线程池,避免频繁创建销毁线程
  4. 死亡通知:通过 linkToDeath() 监控 Binder 服务状态,及时清理资源

整个 startActivity 过程涉及 3-4 次主要的 Binder 调用,通过精心设计的异步回调机制和状态管理,实现了跨进程的 Activity 启动流程。

http://www.dtcms.com/a/494400.html

相关文章:

  • 揭阳市住房和城乡建设局网站网站类游戏网站开发
  • DeviceNet 转 MODBUS TCP罗克韦尔 ControlLogix PLC 与上位机在汽车零部件涂装生产线漆膜厚度精准控制的通讯配置案例
  • 【STM32项目开源】基于STM32的智能衣柜系统
  • python基于web的汽车班车车票管理系统/火车票预订系统/高铁预定系统 可在线选座
  • ssh终端管理多个k8s集群,快速切换配置
  • 景德镇建站公司全国建筑四库一平台
  • 奥运网站模板wordpress在 分栏
  • toLua[七] Examples 06_LuaCoroutine2分析
  • CAD如何生成等高线
  • Java并发工具类详解:Semaphore、CyclicBarrier与CountDownLatch
  • 御剑问情_附带自动假人版_大型3D仙侠类剧情闯关手游_Linux服务端_通用视频架设教程_GM授权网页后台_运营网页后台_安卓苹果IOS双端
  • 基于信息保留与细粒度特征聚合的无人机目标检测
  • AINode部署全指南:从独立部署到Kubernetes集群部署
  • PYcharm——获取天气
  • Kafka多网卡环境配置
  • TypeScript 与淘宝 API:构建类型安全的商品数据查询前端 / Node.js 服务
  • 网站备案名称要求郴州网站排名优化
  • 百度做一个网站多少钱sns营销
  • List<map<String,Object>下划线转驼峰
  • List.subList() 返回值为什么不能强转成 ArrayList
  • phpcms网站转移网站关键词百度排名在下降
  • mac使用本地jdk启动elasticsearch解决elasticsearch启动时jdk损坏问题
  • 手机在初次联网的底层流程-关于EPC信令附着
  • 2025年红米手机上市了哪些款式,本别包含哪些版本,就上市时间、硬件参数、性能、价格等方面进行对比,加入横向竞品对比分析,按价位段划分推荐人群。
  • Go Web 编程快速入门 02 - 认识 net/http 与 Handler 接口
  • 成都网站建设网站制作济南网站制作哪家强
  • 广州做网站的网络公司网站建设美文
  • 云原生时代的数据库字段加密:在微服务与 Kubernetes 中实现合规与敏捷的统一
  • 虚拟机监控全攻略:从基础到云原生实战
  • fastgpt 社区版探究:mongo db 全文检索算法探秘