Creating a Bound Service
When creating a service that provides binding, you must provide an IBinder
that provides the programming interface that clients can use to interact with the service. There are three ways you can define the interface:
Extending the Binder class
If your service is private to your own application and runs in the same process as the client (which is common),you should create your interface by extending the Binder
class and returning an instance of it from onBind()
. The client receives the Binder
and can use it to directly access public methods available in either the Binder
implementation or even the Service
.
This is the preferred technique when your service is merely a background worker for your own application.The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.
(总结:和Client运行在同一个进程,不被其它的进程访问的时候用这个方式)
Using a Messenger
If you need your interface to work across different processes, you can create an interface for the service with a Messenger
. In this manner, the service defines a Handler
that responds to different types of Message
objects. This Handler
is the basis for a Messenger
that can then share an IBinder
with the client, allowing the client to send commands to the service using Message
objects. Additionally, the client can define a Messenger
of its own so the service can send messages back.
This is the simplest way to perform inter process communication (IPC), because the Messenger
queues all requests into a single thread so that you don't have to design your service to be thread-safe.
Using AIDL
AIDL(Android Interface Definition Language) performs all the work to decompose objects into primitives that the operating system can understand and marshall them across processes to perform IPC. The previous technique, using a Messenger
, is actually based on AIDL as its underlying structure. As mentioned above, the Messenger
creates a queue of all the client requests in a single thread, so the service receives requests one at a time. If, however, you want your service to handle multiple requests simultaneously, then you can use AIDL directly. In this case, your service must be capable of multi-threading and be built thread-safe.
To use AIDL directly, you must create an .aidl
file that defines the programming interface.The Android SDK tools use this file to generate an abstract class that implements the interface and handles IPC, which you can then extend within your service.
总结:红色字体的句子很重要,说明了在哪种情况下使用哪种方式!
Note: Only activities, services, and content providers can bind to a service—you cannot bind to a service from a broadcast receiver.
(Broadcast receiver中不能bind service!!)
If you only need to interact with the service while your activity is visible, you should bind during onStart() and unbind during onStop().
If you want your activity to receive responses even while it is stopped in the background, then you can bind during onCreate() and unbind during onDestroy().Beware that this implies that your activity needs to use the service the entire time it's running (even in the background), so if the service is in another process, then you increase the weight of the process and it becomes more likely that the system will kill it.
Additionally, if your service is started and accepts binding, then when the system calls your onUnbind()
method, you can optionally return true
if you would like to receive a call to onRebind()
the next time a client binds to the service. onRebind()
returns void, but the client still receives the IBinder
in its onServiceConnected()
callback. Below, figure 1 illustrates the logic for this kind of lifecycle.