简体   繁体   中英

Android - Binder

I read an article about android's binder. The article says that the processes swap the object references in the shared memory and that it is more efficient than marshalling and unmarshalling...But in fact there is a marshalling and unmarshalling in the IPC-machanism or not?? I'm a bit confused...

Can anyone explain the binder-mechanism or link to a detailed article?

http://marakana.com/s/post/1340/Deep_Dive_Into_Binder_Presentation.htm

This link provides very useful overview in how Binder works as an architecture, and also provides sample code for utilizing each aspects of Binder that are relevant to app developers (Intents, Messenger, AIDL).

The article says that the processes swap the object references in the shared memory

Binder does not use shared memory (ashmem nor pmem). It uses a kernel driver with a fixed-size buffer. Data is copied into and out of the kernel is a secure manner. Maybe the article is using "shared memory" loosely.

I think the confusion is between the Binder protocol, and Android's "Binder" RPC mechanism. As far as the proto is concerned, it's just bytes being copied in and out. The Android platform implements an OO-like RPC mechanism using the Binder kernel driver. This does of course "marshall" objects to bytes and unmarshalls them on the other side back to an object. This is done with help of the Parcel class and Parcelable interface.

Ancient question, but worthy of an up-to-date answer:

The Binder facility makes use of handles, which make it much faster and easier to work with objects. Rather than necessarily marshal the entire object, in some cases only the object handle is returned, after which it can be manipulated through its methods. That means that the bulk of the object (which can be very big) need not be marshaled at all - saving both in CPU and overhead.

As an example, consider how a screen capture is performed. (qv source of screen cap utility), or (as another example) how MediaPlayer works. Binder will acquire a handle to the remote object, but the object doesn't actually go "over the wire". Calling the 'create' method

   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          '............    '

That '*hs' (actually *sh), is a Binder STRONG HANDLE, which means that the descriptor associated with it (in this case, '2') can then be used in subsequent, direct calls, to invoke the IMediaPlayer functionality. This can be demonstrated if that returned descriptor is then probed for its interface:

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

which is as expected (sp). Meaning that now the IMediaPlayer instance's method can be invoked directly.

Btw, while it's true that Binder doesn't use shared memory, the above reply on ashmem isn't exactly accurate. ashmem maps the Anonymous SHared MEMory onto a file descriptor, and then that file descriptor gets moved from process A to B over Binder (which can move file descriptors just as UN*X domain sockets do). Also, Parcels can hold these *SHs (strong handles) whenever you see an IBinderToken item "marshaled" to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM