首先要明白需要的情景,然后对三种方式进行选择:
(一)可以接收Service的信息(获取Service中的方法),但不可以给Service发送信息
(二) 使用Messenger既可以接受Service消息,也可以发送Service消息。但是无法调用Service中的方法。因为利用Message,所以不用担心并发
- 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
Binderclass and returning an instance of it fromonBind(). The client receives theBinderand can use it to directly access public methods available in either theBinderimplementation(得到Service对象,从而获取Service中的方法) or even theService. - 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.
- Service代码如下:
-
Activity代码如下: - 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 aHandlerthat responds to different types ofMessageobjects. ThisHandleris the basis for aMessengerthat can then share anIBinderwith the client, allowing the client to send commands to the service usingMessageobjects. Additionally, the client can define aMessengerof its own so the service can send messages back.This is the simplest way to perform interprocess communication (IPC), because the
Messengerqueues all requests into a single thread so that you don't have to design your service to be thread-safe.If you need your service to communicate with remote processes, then you can use a
Messengerto provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.Here's a summary of how to use a
Messenger:- The service implements a
Handlerthat receives a callback for each call from a client. - The
Handleris used to create aMessengerobject (which is a reference to theHandler). - The
Messengercreates anIBinderthat the service returns to clients fromonBind(). - Clients use the
IBinderto instantiate theMessenger(that references the service'sHandler), which the client uses to sendMessageobjects to the service. - The service receives each
Messagein itsHandler—specifically, in thehandleMessage()method.In this way, there are no methods for the client to call on the service. Instead, the client delivers messages (
Messageobjects) that the service receives in itsHandler.
Messenger和AIDL的比较:
Compared to AIDL
When you need to perform IPC, using a
Messengerfor your interface is simpler than implementing it with AIDL, becauseMessengerqueues all calls to the service, whereas, a pure AIDL interface sends simultaneous requests to the service, which must then handle multi-threading.For most applications, the service doesn't need to perform multi-threading, so using a
Messengerallows the service to handle one call at a time. If it's important that your service be multi-threaded, then you should use AIDL to define your interface.
Binding to a Service
Application components (clients) can bind to a service by calling
bindService(). The Android system then calls the service'sonBind()method, which returns anIBinderfor interacting with the service.The binding is asynchronous.
bindService()returns immediately and does not return theIBinderto the client. To receive theIBinder, the client must create an instance ofServiceConnectionand pass it tobindService(). TheServiceConnectionincludes a callback method that the system calls to deliver theIBinder.
Managing the Lifecycle of a Bound Service
When a service is unbound from all clients, the Android system destroys it (unless it was also started with
onStartCommand()). As such, you don't have to manage the lifecycle of your service if it's purely a bound service—the Android system manages it for you based on whether it is bound to any clients.However, if you choose to implement the
onStartCommand()callback method, then you must explicitly stop the service, because the service is now considered to be started. In this case, the service runs until the service stops itself withstopSelf()or another component callsstopService(), regardless of whether it is bound to any clients.Additionally, if your service is started and accepts binding, then when the system calls your
onUnbind()method, you can optionally returntrueif you would like to receive a call toonRebind()the next time a client binds to the service (instead of receiving a call toonBind()).onRebind()returns void, but the client still receives theIBinderin itsonServiceConnected()callback. Below, figure 1 illustrates the logic for this kind of lifecycle.
(三) 使用AIDL (1.不需要IPC:implement a Binder; 2.需要IPC,不需要并发:use a Messenger; 3.需要IPC,需要并发:AIDL) Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger.- Create the .aidl file
This file defines the programming interface with method signatures.
- Implement the interface
The Android SDK tools generate an interface in the Java programming language, based on your
.aidlfile. This interface has an inner abstract class namedStubthat extendsBinderand implements methods from your AIDL interface. You must extend theStubclass and implement the methods. - Expose the interface to clients
Implement a
Serviceand overrideonBind()to return your implementation of theStubclass.IRemoteService.aidl文件:
// IRemoteService.aidl package com.example.boundservice; // Declare any non-default types here with import statements /** Example service interface */ interface IRemoteService { /** Request the process ID of this service, to do evil things with it. */ int getPid(); /** Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); }
自动生成(eclipse自动,studio需要rebuild)的IRemoteService.java:
- Create the .aidl file
- The service implements a