Messenger夸进程通信的原理

本文介绍了AndroidMessenger类的构造原理,涉及Handlertarget、IBinder和MessengerImpl的交互,展示了如何在服务端和服务端之间通过Binder机制实现跨进程通信,以及Handler在消息处理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,所以一次只能处理一条信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值