我读了一篇关于 android 的活页夹的文章。文章说进程交换共享内存中的对象引用并且它比编组和解组更有效......但实际上在IPC机制中是否存在编组和解组?我有点困惑……
任何人都可以解释活页夹机制或链接到详细文章吗?
我读了一篇关于 android 的活页夹的文章。文章说进程交换共享内存中的对象引用并且它比编组和解组更有效......但实际上在IPC机制中是否存在编组和解组?我有点困惑……
任何人都可以解释活页夹机制或链接到详细文章吗?
Binder 是一种在内核中运行的优化编组方法。
关于它的几个链接:
http://www.cubrid.org/blog/dev-platform/binder-communication-mechanism-of-android-processes/ http://lukejin.wordpress.com/2011/03/13/android%E4%B8% AD%E7%9A%84binder/
http://marakana.com/s/post/1340/Deep_Dive_Into_Binder_Presentation.htm
此链接提供了关于 Binder 如何作为架构工作的非常有用的概述,还提供了用于利用与应用程序开发人员相关的 Binder 的各个方面(Intents、Messenger、AIDL)的示例代码。
古老的问题,但值得一个最新的答案:
Binder 工具使用了句柄,这使得处理对象变得更快、更容易。在某些情况下,不必编组整个对象,而是只返回对象句柄,之后可以通过其方法对其进行操作。这意味着对象的大部分(可能非常大)根本不需要编组 - 节省 CPU 和开销。
例如,考虑如何执行屏幕捕获。(屏幕截图实用程序的 qv 源),或(作为另一个示例)MediaPlayer 的工作方式。Binder 将获取远程对象的句柄,但该对象实际上并没有“通过网络”。调用“创建”方法
virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client,
audio_session_t audioSessionId = AUDIO_SESSION_ALLOCATE)
flame:/ $ service call media.player 1
Result: Parcel(
0x00000000: 73682a85 00000113 00000002 00000000 '.*hs............'
0x00000010: 00000000 00000000 0000000c '............ '
'*hs'(实际上是 *sh)是一个 Binder STRONG HANDLE,这意味着与其关联的描述符(在本例中为 '2')可以在后续直接调用中使用,以调用 IMediaPlayer 功能。如果随后针对其接口探测返回的描述符,则可以证明这一点:
flame:/ $ /data/local/tmp/bdsm call media.player 1
Got handle to android.media.IMediaPlayerService
Object 0 (desc 2) is a handle to android.media.IMediaPlayer
这是预期的(sp)。这意味着现在可以直接调用 IMediaPlayer 实例的方法。
顺便说一句,虽然 Binder 确实不使用共享内存,但上述关于 ashmem 的回复并不完全准确。ashmem 将匿名共享内存映射到文件描述符,然后该文件描述符通过 Binder 从进程 A 移动到 B(它可以像 UN*X 域套接字一样移动文件描述符)。此外,每当您看到 IBinderToken 项目“编组”到它时,Parcels 都可以持有这些 *SH(强句柄)。
文章说进程交换共享内存中的对象引用
Binder 不使用共享内存(ashmem 或 pmem)。它使用具有固定大小缓冲区的内核驱动程序。将数据复制进和复制出内核是一种安全的方式。也许这篇文章松散地使用了“共享内存”。
我认为混淆是在Binder 协议和Android 的“Binder” RPC 机制之间。就原型而言,它只是被复制进出的字节。Android 平台使用 Binder 内核驱动程序实现了类似 OO 的 RPC 机制。这当然会将对象“编组”为字节,并在另一侧将它们解组回对象。这是在Parcel
类和Parcelable
接口的帮助下完成的。