https://developer.android.com/guide/components/bound-services.html


  如果您的服务是您自己的应用程序专用的,并且与客户端在同一进程中运行(这很常见),则应通过扩展Binder类并从onBind()返回它的实例来创建接口。客户端收到Binder,并可以使用它直接访问Binder实现或服务中可用的公共方法。
  
  当您的服务只是您自己的应用程序的后台工作程序时,这是首选技术。您不会以这种方式创建界面的唯一原因是,您的服务被其他应用程序使用或跨单独的进程使用。
  
  如果需要您的界面跨不同的流程工作,则可以使用Messenger来为服务创建一个界面...


这似乎意味着您不会使用Binder进行进程间通信,但是IBinder documentation则相反:


  可远程对象的基本接口,轻量级远程过程调用机制的核心部分,旨在在执行进程内和跨进程调用时实现高性能。该接口描述了用于与可远程对象进行交互的抽象协议。不要直接实现此接口,而应从Binder扩展。
  
  关键的IBinder API是由Binder.onTransact()匹配的transact()。这些方法使您可以分别向IBinder对象发送调用并接收对Binder对象的调用。此事务API是同步的,因此直到目标从Binder.onTransact()返回之前,对transact()的调用才返回。这是调用本地进程中存在的对象时的预期行为,并且底层的进程间通信(IPC)机制可确保跨进程时应用这些相同的语义。


Binder documentation


  但是,您可以直接从Binder派生实现自己的自定义RPC协议,也可以直接实例化原始Binder对象以用作可以在各个进程之间共享的令牌。
  
  此类只是一个基本的IPC原语...


其他许多页面也提到了IPC上下文中的活页夹。我有什么误会?

最佳答案

IBinder为可移动对象提供基本接口。
Binder是IBinder的实现,它提供标准支持,以创建可远程对象的本地实现。

当服务和客户端都在同一进程中运行时,只需扩展Binder并返回Binder子类的实例即可通过绑定到服务来与服务进行通信,因为Binder是提供标准支持的IBinder实现。创建可移除对象的本地实现。

当服务在单独的进程中运行并且服务的客户端可以在任何其他进程中运行时,我们需要实现IBinder并提供实现,该实现为可远程对象的远程实现提供支持。这可以通过以下两种方式之一来实现:

使用AIDL

使用AIDL,我们可以编写一个要公开的接口。然后,aidl工具可以解析此文件并自动生成Stub和一些IPC所有应用程序通用的样板代码。然后,我们可以扩展Interface.Stub以在服务端提供实现。

客户可以在项目中包含此AIDL文件,并且aidl工具会自动生成IPC代码。现在,客户端可以绑定到您的服务并使用AIDL文件中声明的接口进行通信。

使用Messenger

Messenger是对Handler的引用,其他人可以使用它向其发送消息。通过在一个进程中创建一个指向处理程序的Messenger并将该Message传递给另一个进程,可以实现跨进程的基于消息的通信。此IPC是使用AIDL本身在内部实现的。 HereIMessenger.aidl接口,Messenger在内部使用该接口公开客户端可以用来与主机进程进行通信的合同。

摘要

IBinder可以用于进程内和进程间通信。将其用于进程间通信时,只需使用AIDL公开接口即可。

关于android - 为什么Android绑定(bind)服务文档建议IBinder无法跨进程使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45143078/

10-09 04:33