2011年3月26日 星期六

[LVL] AIDL

[IPC]

* IPC: Inter-Process Communication

* 程序和程序間是需要通訊的,我們稱此能力為程序間通訊。

* IPC 就是數種在 MultiProcess 下相互溝通的方法,其實不只是 process,甚至可推及 thread 間及 computer 間的溝通。這些技術包含像 synchronization, message passing, shared memory, memory-mapped files, pipe, socket…等等。


[AIDL]

* AIDL: Android Interface Definition Language

* 可以協助我們快速地建構Android程序間的通訊介面 (如在Windows系統中存在IPC管道服務、MailSolt郵槽、消息等方法)。

* Using AIDL is necessary only if:
  • You allow clients from different applications to access your service for IPC
  • Want to handle multithreading in your service.

* Be aware that calls to an AIDL interface are direct function calls. You should not make assumptions about the thread in which the call occurs. What happens is different depending on whether the call is from a thread in the local process or a remote process.

* Calls made from the local process are executed in the same thread that is making the call. If this is your main UI thread, that thread continues to execute in the AIDL interface. If it is another thread, that is the one that executes your code in the service. Thus, if only local threads are accessing the service, you can completely control which threads are executing in it (but if that is the case, then you shouldn't be using AIDL at all, but should instead create the interface by implementing a Binder).

* In other words, an implementation of an AIDL interface must be completely thread-safe.

* When used, a remote call does not block; it simply sends the transaction data and immediately returns. The implementation of the interface eventually receives this as a regular call from the Binder thread pool as a normal remote call. If oneway is used with a local call, there is no impact and the call is still synchronous.

* To create a bounded service using AIDL, follow these steps:
  1. Create the .aidl file:
    This file defines the programming interface with method signatures.
  2. Implement the interface:
    The Android SDK tools generate an interface in the Java programming language, based on your .aidl file. This interface has an inner abstract class named Stub that extends Binder and implements methods from your AIDL interface. You must extend the Stub class and implement the methods.
  3. Expose the interface to clients:
    Implement a Service and override onBind() to return your implementation of the Stub class.

* The parameters and return values can be of any type, even other AIDL-generated interfaces.

* Each .aidl file must define a single interface and requires only the interface declaration and method signatures.

* There are a few rules you should be aware of when implementing your AIDL interface:
  • Incoming calls are not guaranteed to be executed on the main thread, so you need to think about multithreading from the start and properly build your service to be thread-safe.
  • By default, RPC calls are synchronous. If you know that the service takes more than a few milliseconds to complete a request, you should not call it from the activity's main thread, because it might hang the application (Android might display an "Application is Not Responding" dialog)—you should usually call them from a separate thread in the client.
  • No exceptions that you throw are sent back to the caller.

* Supporting the Parcelable interface is important because it allows the Android system to decompose objects into primitives that can be marshalled across processes.

* To create a class that supports the Parcelable protocol, you must do the following:
  • Make your class implement the Parcelable interface.
    Implement writeToParcel, which takes the current state of the object and writes it to a Parcel.
  • Add a static field called CREATOR to your class which is an object implementing the Parcelable.Creator interface.
  • Finally, create an .aidl file that declares your parcelable class.
  • If you are using a custom build process, do not add the .aidl file to your build. Similar to a header file in the C language, this .aidl file isn't compiled.

* Here are the steps a calling class must take to call a remote interface defined with AIDL:
  1. Include the .aidl file in the project src/ directory.
  2. Declare an instance of the IBinder interface (generated based on the AIDL).
  3. Implement ServiceConnection.
  4. Call Context.bindService(), passing in your ServiceConnection implementation.
  5. In your implementation of onServiceConnected(), you will receive an IBinder instance (called service). Call YourInterfaceName.Stub.asInterface((IBinder)service) to cast the returned parameter to YourInterface type.
  6. Call the methods that you defined on your interface. You should always trap DeadObjectException exceptions, which are thrown when the connection has broken; this will be the only exception thrown by remote methods.
  7. To disconnect, call Context.unbindService() with the instance of your interface.

* A few comments on calling an IPC service:
  • Objects are reference counted across processes.
  • You can send anonymous objects as method arguments.



* Reference
- Android Interface Definition Language (AIDL)
- 運用AIDL來打造Android程序間的通訊
- [轉]Android 的AIDL是啥?
- 一千零一夜之 Android Binder
- Android的IPC機制及多線程技術 **
- 深刻解析 Android 的 AIDL 介面(一) **
- Inter-Process Communication (IPC)

沒有留言:

張貼留言