1 概述
- Messenger是一种轻量级的IPC方案,其底层实现原理就是AIDL,它对AIDL做了一次封装,所以使用方法会比AIDL简单,由于它的效率比较低,一次只能处理一次请求,所以不存在线程同步的问题。
5713484-338c2db71a490dfc.png
2 示例(通过Messenger实现客户端与服务端跨进程通信)
2.1 服务端
在其他进程
public class MessagerService extends Service {
private Messenger messenger = new Messenger(new MessaengerHandler());
private static class MessaengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case Constants.CLENT_MESSAGE:
Log.i("GELAOLITOU", "收到消息:" + msg.getData().get(Constants.KEY));
//客户端Messenger
Messenger msgr_client = msg.replyTo;
Message mes_reply = Message.obtain(null, Constants.SERVER_MESSAGE);
Bundle bundle = new Bundle();
bundle.putString(Constants.REPLY_KEY, "你的信息我已经收到,现在就回复你");
mes_reply.setData(bundle);
try {
msgr_client.send(mes_reply);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}
2.2 客户端
public class MessagerClientActivity extends BaseActivity {
public static void show(Activity activity) {
Intent intent = new Intent(activity, MessagerClientActivity.class);
activity.startActivity(intent);
}
private Messenger serverMessager;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取服务端messager
serverMessager = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//创建客户端messager
private Messenger mGetReplyMessenger = new Messenger(new MessengerClientHandler(this));
//客户端消息处理
private static class MessengerClientHandler extends Handler {
private WeakReference<MessagerClientActivity> messagerClientActivityWeakReference;
private MessengerClientHandler(MessagerClientActivity messagerClientActivity) {
messagerClientActivityWeakReference = new WeakReference<MessagerClientActivity>(messagerClientActivity);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.SERVER_MESSAGE:
MessagerClientActivity activity = messagerClientActivityWeakReference.get();
if (activity != null) {
activity.handleMessage(msg);
}
break;
}
}
}
private void handleMessage(Message msg) {
content.setText("收到 服务端的消息,消息内容是" + msg.getData().getString(Constants.REPLY_KEY));
}
private TextView content;
@Override
protected int getLayoutResId() {
return R.layout.activity_messager_client;
}
@Override
protected void initView() {
findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//向服务端发送消息
sendMessage();
}
});
content = findViewById(R.id.content);
}
@Override
protected void initData() {
super.initData();
Intent intent = new Intent(this, MessagerService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
private void sendMessage() {
if (serverMessager == null) {
return;
}
//创建一个what值为Constants.CLENT_MESSAGE的message
Message message = Message.obtain(null, Constants.CLENT_MESSAGE);
Bundle bundle = new Bundle();
bundle.putString(Constants.KEY, "我是来自客户端的信息");
message.setData(bundle);
//将客户端Messenger传递给服务端
message.replyTo = mGetReplyMessenger;
try {
serverMessager.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3 源码分析
public final class Messenger implements Parcelable {}
3.1 类结构
TIM截图20180831093732.png3.2 构造方法
private final IMessenger mTarget;
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
-
- 参数是Handler
- 传入一个Handler作为参数创建一个新的Messenger
- 通过该Messenger发送的任何消息对象将会出现在这个Handler里面,就像Handler直接调用sendMessage(Message)一样。入参target接收这些已经发送的消息。
-
- 参数是IBinder
- 根据原始的IBinder来创建一个Messenger对象,可以通过getBinder()方法来获取这个IBinder对象。入参target其实就是这个Messenger与之通信的
*其中IMessenger.Stub.asInterface(target);这个方法简直就是AIDL方式
3.2.1 getIMessenger()
[Handler.java]
IMessenger mMessenger;
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
- IMessenger,Stub --->IMessenger.aidl--Messenger底层是基于AIDL的
- 当发送消息的时候,调用是Handler.this.sendMessage(msg);,其实就是自己调用的sendMessage(msg)方法而已。
3.2.2 IMessenger.Stub.asInterface(target)
Android跨进程通信IPC之19——AIDL
返回一个封装过的Stub.Proxy,也是一个代理类
3.3 其他两个重要方法
3.3.1 Messenger.getBinder()方法
public IBinder getBinder() {
return mTarget.asBinder();
}
mTarget.asBinder()等价于代理类Stub.Proxy.asBinder()
请看Android跨进程通信IPC之19——AIDL
asBinder()中返回--
3.3.2 send(Message msg)方法
public void send(Message message) throws RemoteException {
mTarget.send(message);
}
发送一个message对象到 messagerHandler。这里我们传递的参数是一个Message对象
上面内容 未完待续
网友评论