Messenger构造方法
-
Messager(Handler target)
public Messenger(Handler target) { mTarget = target.getIMessenger(); } final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; } } // MessengerImpl就是一个IBinder对象 private final class MessengerImpl extends IMessenger.Stub {}
一方面是用于处理消息,另一方面是为了Messager保存当前的进程IBinder对象,以便在其他进程发送消息到当前进程中处理
-
Messager(IBinder target)
public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); }
让Messager保存指定的进程IBinder对象,以便后面用来发送消息到指定的进程处理
用法
- 服务进程中创建一个Messenger(Handler),并且当前的Messenger内部已经绑定了当前进程的IBinder对象IMessenger.Stub即MessengerImpl,然后可以通过Service.onBind()方法将服务进程绑定的IBinder对象传出去,供客户端调用,在Messenger.Handler中,通过message.replyTo拿到客户端的Messenger,然后进行Messenger.send(Message),这就完成了服务端向客户端的通信
// 服务端进程 class ServerService extends Service{ // 创建服务进程的Messenger,并绑定服务进程的IBinder对象 private Messenger messenger = new Messenger(new Handler(){ @Override public void handleMessage(Message msg){ switch(msg.what){ case 1: String name = msg.getData().getString("name"); Log.d("tag","收到客户端进程的消息name:"+name); Message message = Message.obtain(); message.what = 2; Bundle bundle=new Bundle(); bundle.putString("name","hhh"); message.setData(bundle); try{ //向客户端发消息 //replyTo其实指向的就是客户端的Messenger msg.replyTo.send(message); }cache(Exception e){ } } }; @Override public IBinder onBind(){ // 返回服务进程的IBinder对象,给客户端进程使用 return messenger.getIBinder(); } }
- 客户端进程中通过bindService去绑定服务,拿到服务端提供的IBinder对象,然后创建一个Messenger(IBinder),此时这个Messenger已经绑定了服务进程的IBinder对象,这样,通过该Messenger.send(Message)都会到服务进程的MessengerImpl.send(Message)中执行,然后将message发送到Messenger中的handler处理,这就完成了客户端像服务端通信的过程
private Messenger messenger; bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { // 创建一个messenger,并绑定有服务进程IBinder的对象, // 用户向服务端发消息 messenger=new Messenger(iBinder); Message message=new Message(); message.what=1; Bundle bundle=new Bundle(); bundle.putString("name","花花"); message.setData(bundle); // 将客户端进程的Messenger绑定到message中, // 供在服务进程中拿到客户端进程的Messenger用于通信处理 message.replyTo=mMessengerHandler; try { // 像服务端发送消息 messenger.send(message); } catch (RemoteException e) { throw new RuntimeException(e); } } @Override public void onServiceDisconnected(ComponentName componentName) { } },Service.BIND_AUTO_CREATE); private Messenger mMessengerHandler = new Messenger(new Handler(){ @Override public void handleMessage(Message msg){ switch(msg.what){ case 1: String name = msg.getData.getString("name"); Log.d("tag","收到来自服务进程的消息name:"+name); } } } }; // 客户端就可以拿到这个绑定了服务进程的messenger,去不断的与服务端通信
总结
- Messenger跨进程通信,底层实际上就是通过Binder机制
- 由于处理消息是使用的是Handler,所以一次只能处理一条信息