一句话说透Android里面的跨进程关键字in、out、inout、oneway

759 阅读2分钟

一、inoutinout:数据流向与性能

在 AIDL 中,inoutinout 关键字用于控制非基本类型参数的跨进程传递方向。它们的区别主要体现在数据拷贝的次数客户端对象是否会被修改

1. in(输入)

  • 数据流向:客户端 → 服务端(单向)。
  • 底层实现:客户端将数据拷贝到 Binder 驱动,驱动再将数据拷贝到服务端。只发生一次数据拷贝。
  • 副作用:服务端对参数的修改不会影响客户端的原始对象。
  • 使用场景:传递无需服务端修改的输入参数,如查询请求的 ID、用户信息。

2. out(输出)

  • 数据流向:服务端 → 客户端(单向)。
  • 底层实现:客户端传入的参数会被忽略。服务端需新建对象并填充数据,然后将数据拷贝到 Binder 驱动,驱动再将数据拷贝到客户端。
  • 副作用:客户端的原始对象会被服务端的修改覆盖。
  • 使用场景:从服务端获取新生成的数据,如获取查询结果、生成的用户信息。

3. inout(双向)

  • 数据流向:客户端 ↔ 服务端(双向)。
  • 底层实现:发生两次数据拷贝,一次从客户端到服务端(输入),另一次从服务端返回到客户端(输出)。
  • 副作用:客户端的原始对象会被服务端的修改覆盖。
  • 使用场景:需要服务端处理并返回修改后的数据,如对用户信息的更新、状态的同步。

二、oneway:异步调用与线程模型

  • 核心作用oneway 关键字用于标记一个方法为异步调用。客户端调用 oneway 方法后,会立即返回,不阻塞当前线程

  • 线程模型

    • 客户端:调用 oneway 方法时,Binder 驱动会立即返回。调用者线程不会被阻塞。
    • 服务端oneway 方法会在一个独立的 Binder 线程上执行。如果该方法涉及到耗时操作,它不会阻塞服务端的其他 Binder 线程。
  • 使用限制

    • oneway 方法不能有返回值(必须是 void)。
    • oneway 方法不能有 outinout 参数。
  • 使用场景:触发无需即时反馈的操作,如日志记录、数据上报、发送通知等。


三、总结

关键字数据方向阻塞类型数据拷贝次数
in客户端 → 服务端同步(阻塞客户端)一次
out服务端 → 客户端同步(阻塞客户端)一次
inout客户端 ↔ 服务端同步(阻塞客户端)两次
oneway无返回值异步(不阻塞客户端)零或一次

通过这些关键字,开发者可以精准控制跨进程通信的数据流向和方法行为,从而优化性能、简化逻辑,并构建出高效、安全的 IPC 机制。