Messenger——Messenger使用和原理

Messenger——Messenger使用和原理Messenger是一种轻量级的IPC通信方案,对AIDL进行了封装,可以在不同进程中传递Message对象

1、概述

Messenger是一种轻量级的IPC通信方案,对AIDL进行了封装,可以在不同进程中传递Message对象。

2、使用Messenger通信

Server端代码

public class MessengerService extends Service { 
   
    public static final String TAG = "MyMessenger";
    public static final int MSG_FROMCLIENT = 1000;
    public static final int MSG_FROMSERVER = 1001;

    @Override
    public void onCreate() { 
   
        super.onCreate();
    }

    private Handler mHandler = new Handler(Looper.myLooper()) { 
   
        @Override
        public void handleMessage(@NonNull Message msg) { 
   
            switch (msg.what) { 
   
                case MSG_FROMCLIENT:
                    Log.d(TAG, "receive message from client:" + msg.getData().getString("msg"));

                    Messenger messenger = msg.replyTo;
                    Message message = Message.obtain(null, MSG_FROMSERVER);
                    Bundle bundle = new Bundle();
                    bundle.putString("rep", "message form server");
                    message.setData(bundle);
                    try { 
   
                        messenger.send(message);
                    } catch (RemoteException e) { 
   
                        e.printStackTrace();
                    }
                    break;
            }
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) { 
   
        return new Messenger(mHandler).getBinder();
    }
}

Service端接收Client端发送的消息,并返回一个消息。Server端要点是创建Handler对象,并在其handleMessage方法中处理Client端发送的消息。如果要返回消息给Client端,则需要Client发送消息时传递Client端的Messenger对象到Server端。同样的Client端要发送消息到Server端,也是通过Server端传递过去的Messenger对象。

Client端代码

public class MainActivity extends AppCompatActivity { 
   

    private Handler mHandler = new Handler(Looper.myLooper()) { 
   
        @Override
        public void handleMessage(@NonNull Message msg) { 
   
            switch (msg.what) { 
   
                case MessengerService.MSG_FROMSERVER:
                    Log.d(MessengerService.TAG, "received message from server: " + msg.getData().getString("rep"));
                    break;
            }
        }
    };

    private ServiceConnection mServiceConnection = new ServiceConnection() { 
   
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) { 
   
            Messenger messenger = new Messenger(service);
            Message message = Message.obtain(null, MessengerService.MSG_FROMCLIENT);
            Bundle bundle = new Bundle();
            bundle.putString("msg", "message form client");
            message.setData(bundle);
            message.replyTo = new Messenger(mHandler);
            try { 
   
                messenger.send(message);
            } catch (RemoteException e) { 
   
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) { 
   

        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() { 
   
        super.onDestroy();
        unbindService(mServiceConnection);
    }
}

bindService时回调onServiceConnected,获取service返回的IBinder对象,由此重构Messenger对象,并用此Messenger对象发送消息给Server端。同时,如果需要处理Server端返回的消息,则需要创建一个Messenger对象并包含Handler对象,将其设置到Message对象的replyTo属性中,并将其传递到Server端,Server端通过这个replyTo获取的Messenger对象发送消息回Client端。

3、Messenger原理探究

从Messenger的使用中可以看出,Messenger通信依赖Binder、Handler和Message。Handler机制是Android线程间通信的机制,BInder是Android进程间通信的机制。

  • 构造函数
public Messenger(Handler target) { 
   
    mTarget = target.getIMessenger();
}
public Messenger(IBinder target) { 
   
    mTarget = IMessenger.Stub.asInterface(target);
}

messenger有两个构造函数,分别是传入一个Handler对象和一个IBinder类型的对象作为参数,都会去设置mTarget属性。
先来看一下Handler作为参数的情况,调用的是Handler中的getIMessenger方法。

final IMessenger getIMessenger() { 
   
    synchronized (mQueue) { 
   
        if (mMessenger != null) { 
   
            return mMessenger;
        }
        mMessenger = new MessengerImpl();
        return mMessenger;
    }
}

返回的是IMessenger对象,如果Handler中已经设置了该对象则直接返回,如果没有设置,则返回一个MessengerImpl对象。MessengerImpl是Handler中的内部类,继承自IMessenger.Stub,并重写了send方法。

private final class MessengerImpl extends IMessenger.Stub { 
   
    public void send(Message msg) { 
   
        msg.sendingUid = Binder.getCallingUid();
        Handler.this.sendMessage(msg);
    }
}

可以看出IMessenger是一个aidl接口,里面有一个send方法。
另外一个构造函数就更直接了,直接调用asInterface方法返回一个IMessenger的实例。

  • 发送消息
public void send(Message message) throws RemoteException { 
   
    mTarget.send(message);
}

调用的是mTarget的send方法,因为mTarget是IMessenger的实例,调用的是Handler中MessengerIml内部类的send方法。从上面的方法中可以看到实际调用的就是Handler中的sendMessage方法。

  • 总结
    Messenger实际是通过Binder来实现跨进程通信,通过Handler机制来处理消息循环。Messenger封装Handler来进行消息的发送和处理,消息发送后通过Binder完成进程间通信。

今天的文章Messenger——Messenger使用和原理分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64622.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注