標籤:
前面LocalService 主要是提供同一Application中組件來使用,如果希望支援不同應用或進程使用Service。可以通過Messenger。使用Messgener可以用來支援處理序間通訊而無需使用AIDL。
下面步驟說明裡Messenger的使用方法:
- 在Service中定義一個Handler來處理來自Client的請求。
- 使用這個Handler建立一個Messenger (含有對Handler的引用).
- Messenger建立一個IBinder對象返回給Client( onBind方法)。
- Client 使用從Service返回的IBinder重新構造一個Messenger 對象,提供這個Messenger對象可以給Service 發送訊息。
- Service提供Handler接受來自Client的訊息Message. 提供handleMessage來處理訊息。
在這種方式下,Service沒有定義可以供Client直接調用的方法。而是通過”Message”來傳遞資訊。
本例Messenger Service 涉及到兩個類 MessengerServiceActivities 和 MessengerService.
首先看看Service的定義,在MessengerService定義了一個IncomingHandler ,用於處理來自Client的訊息。
/** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_SET_VALUE: mValue = msg.arg1; for (int i=mClients.size()-1; i>=0; i--) { try { mClients.get(i).send(Message.obtain(null, MSG_SET_VALUE, mValue, 0)); } catch (RemoteException e) { // The client is dead. Remove it from the list; // we are going through the list from back to front // so this is safe to do inside the loop. mClients.remove(i); } } break; default: super.handleMessage(msg); } } }
然後使用這個IncomingHandler定義一個Messenger:
/** * Target we publish for clients to send messages to IncomingHandler. */ final Messenger mMessenger = new Messenger(new IncomingHandler());
應為這種方法採用的“Bound” Service模式,onBind 需要返回一個IBind對象, 可以通過mMessenger.getBinder()返回與這個Messenger關聯的IBinder對象,Client可以通過這個IBinder 對象重新構造一個Messenger對象,從而建立起與Service之間的通訊鏈路。
/** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ @Override public IBinder onBind(Intent intent) { return mMessenger.getBinder(); }
再看看Client 的代碼MessengerServiceActivities 在 ServiceConnection的 onServiceConnected的定義,這個方法返回MessengerService 的onBind 定義的IBinder對象:
public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. We are communicating with our // service through an IDL interface, so get a client-side // representation of that from the raw service object. mService = new Messenger(service); mCallbackText.setText("Attached."); // We want to monitor the service for as long as we are // connected to it. try { Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); // Give it some value as an example. msg = Message.obtain(null, MessengerService.MSG_SET_VALUE, this.hashCode(), 0); mService.send(msg); } catch (RemoteException e) { // In this case the service has crashed before we could even // do anything with it; we can count on soon being // disconnected (and then reconnected if it can be restarted) // so there is no need to do anything here. } // As part of the sample, tell the user what happened. Toast.makeText(Binding.this, R.string.remote_service_connected, Toast.LENGTH_SHORT).show(); }
本例實現了Client與Service 之間的雙向通訊,因此在Client也定義了一個Messenger對象mMessenger,用於處理來自Service的訊息。
有了 mService對象,就可以使用send向Service發送訊息,如過需要Service 返回資訊,可以定義message.replyTo 對象。
【起航計劃 036】2015 起航計劃 Android APIDemo的魔鬼步伐 35 App->Service->Messenger Service Messenger實現處理序間通訊