Skip to content
阅读进度

Agent 与系统服务怎样通过 Binder / AIDL 通信? ​

返回 Framework 与系统服务 目录

标准回答 ​

Binder 是 Android 常用的进程间通信机制,AIDL 用来定义跨进程接口并生成代理和 Stub。我会把耗时操作设计成“提交任务、返回受理结果、异步通知进度”,避免让一次同步调用一直等到设备动作完成。

普通远程 AIDL 调用通常同步等待服务端返回,服务端会在 Binder 线程池处理请求,所以既不能在 UI 主线程做可能很慢的远程调用,也不能长期占用 Binder 线程做网络或推理。服务端应先校验调用者和参数,再把已授权任务交给合适的执行器。调用身份必须在 Binder 入口捕获和校验,不能切到工作线程后再假设还能读到原始调用者。

回调同样要考虑线程。远程回调到达客户端时不能直接操作 View,应切回主线程,并核对 taskId、当前页面生命周期和任务版本,防止旧结果覆盖新页面。共享任务状态可以通过串行执行器管理,或者使用明确的同步机制保护。

服务进程可能死亡。我会处理 RemoteException,结合绑定状态或死亡通知使旧代理失效,有限退避重连,并在重连后查询任务状态。有副作用的任务不会因为 Binder 断开就直接重发:断开只证明通信失败,不能证明动作没有执行。

关键机制 ​

  • 同步调用会等待;oneway 改变远程调用的等待方式,不证明工作已经完成。
  • Binder 线程负责快速鉴权与转交;业务执行、主线程 UI 更新各自有清晰边界。
  • 协议包含请求标识、状态查询、取消与结果;重连后先核对状态。

通俗例子 ​

UI 提交“连接设备”后立即显示执行中。服务返回已受理并在工作线程连接;结果通过回调传回,UI 仅接收属于当前任务的事件。若中途服务重启,则进入重连与状态核对流程。

追问与回答 ​

把接口全改成 oneway 就能解决卡顿吗? ​

不能。oneway 可以让远程调用不等待业务返回,但服务端仍可能排队、抢锁或耗时,也没有自动获得可靠完成通知。我会先区分短查询和长任务,长任务使用提交、回调和状态查询协议,再处理限流与工作线程。对同进程本地调用,oneway 也不会让方法自动变异步。

为什么持锁调用远程服务容易出问题? ​

远程调用时长不可控,而且对方可能再回调当前进程。如果当前线程拿着锁等待对方,而回调又要拿这把锁,就可能形成死锁。我会在锁内只做必要的状态读取或快照,在锁外执行 IPC,返回后再次核对状态版本;必须跨步骤保持一致时,用明确状态机代替长时间持锁。

易混淆点 ​

本地 AIDL 调用仍在调用线程同步执行,oneway 对本地调用不产生同样的异步效果。Service 组件本身也不等于一条后台线程。

参考资料 ​

内容来源 ​

用完整回答理解机制,用真实证据解释项目。