Using a Messenger
接上文(Android Service的綁定 基礎概念篇),綁定的service主要有三種不同的實現方法,在此介紹第二種方法。
如果你需要你的service和其他進程通信,那么你可以使用一個Messenger來提供這個接口。
這種方法允許你在不使用 AIDL的情況下,進行跨進程通信IPC。
實現步驟
下面是一個如何使用 Messenger的小總結:
1.service實現一個 Handler 接收客戶端每一次調用的回調。
2. Handler 用來創建一個Messenger對象,它是一個Handler的引用。
3. Messenger創建一個 IBinder
,
service從 onBind()
中把它返回給客戶端。
4.客戶端使用這個IBinder來實例化Messenger (service的Handler的引用),客戶端使用它來向service發送Message對象。
5.service在它的Handler中接收每一個Message對象,在它的 handleMessage()
方法中。
程序實例
下面是一個使用Messenger接口的例子:
public class MessengerService extends Service { /** Command to the service to display a message */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } /** * Target we publish for clients to send messages to IncomingHandler. */ final Messenger mMessenger = new Messenger(new IncomingHandler()); /** * When binding to the service, we return an interface to our messenger for * sending messages to the service. */ @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT) .show(); return mMessenger.getBinder(); } }
注意 Handler中的 handleMessage()
方法是service接收到來的 Message並且決定做什么的地方。
客戶端需要做的僅僅是創建一個基於service所返回的 IBinder
的 Messenger,然后用 send()方法發送信息。
比如,這里有一個簡單的activity和service綁定並且發送信息給service:
public class ActivityMessenger extends Activity { /** Messenger for communicating with the service. */ Messenger mService = null; /** Flag indicating whether we have called bind on the service. */ boolean mBound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = new Messenger(service); mBound = true; } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. mService = null; mBound = false; } }; public void sayHello(View v) { if (!mBound) return; // Create and send a message to the service, using a supported 'what' // value Message msg = Message .obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to the service bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } }
注意這個例子並沒有展示service如何響應客戶端,如果你想要service響應,你需要在客戶端中創建一個 Messenger。
然后當客戶端接收到onServiceConnected()回調方法時,它會發送一個 Message到service,在它的send()
方法的replyTo參數中包含了客戶端的Messenger。
參考資料
API Guides:Bound Services
http://developer.android.com/guide/components/bound-services.html