`
lyunabc
  • 浏览: 527732 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

Android ApiDemos示例解析(41):App->Service->Messenger Service

 
阅读更多

前面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。

final Messenger mMessenger = new Messenger(new IncomingHandler());

应为这种方法采用的“Bound” Service模式,onBind 需要返回一个IBind对象, 可以通过mMessenger.getBinder()返回与这个Messenger关联的IBinder对象,Client可以通过这个IBinder对象重新构造一个Messenger对象,从而建立起与Service之间的通信链路。

@Override
public IBinder onBind(Intent intent) {
 return mMessenger.getBinder();
}

再看看Client 的代码MessengerServiceActivities 在 ServiceConnection的 onServiceConnected的定义,这个方法返回MessengerService 的onBind 定义的IBinder对象:

/** Messenger for communicating with service. */
 Messenger mService = null;
 
....
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.
 }
 ....

本例实现了Client与Service 之间的双向通信,因此在Client也定义了一个Messenger对象mMessenger,用于处理来自Service的消息。

有了 mService对象,就可以使用send向Service发送消息,如过需要Service 返回信息,可以定义message.replyTo 对象。





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics