【Android】进程通信IPC——Messenger
16lz
2021-01-25
Messenger可以说是信使,用于不同进程间通信。Messenger是轻量级的IPC,内部是使用了AIDL。
服务端
创建Service,使用Handler参数的Messenger构造方法,具体的数据获取等操作放在Handler#handleMessage()方法中。
public class MessengerService extends Service { private static final String TAG = "MessengerService"; Messenger messenger = new Messenger(new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { String message = (String) msg.getData().get("message"); Log.i(TAG, "服务端收到消息:" + message); Message replyMessage = Message.obtain(); replyMessage.what = 2; Bundle bundle = new Bundle(); bundle.putString("message","服务端已收到客户端消息,内容如下---"+message); replyMessage.setData(bundle); try { msg.replyTo.send(replyMessage); } catch (RemoteException e) { e.printStackTrace(); } } } }); @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); }}
客户端
客户端使用bindService方式关联启动服务,在ServiceConnection#onServiceConnected回调中获取服务端Messenger。
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //服务端Messenger serviceMessenger = new Messenger(service); } @Override public void onServiceDisconnected(ComponentName name) { serviceMessenger = null; } };
向服务端Messenger发送消息,并设置回复处理的客户端Messenger。
Message message = Message.obtain(); message.what = 1; Bundle bundle = new Bundle(); bundle.putString("message", String.format("客户端%s发送信息", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); message.setData(bundle); //设置回复处理的Messenger message.replyTo = clientMessenger; if (serviceMessenger != null) { try { serviceMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } }
源码分析
Messenger的构造函数,在创建客户端和服务端Messenger的时候有用到。
public Messenger(Handler target) { mTarget = target.getIMessenger(); }
getIMessenger()的源码可以看到就是一个继承了IMessenger.Stub的类,
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的AIDL如下,里面提供了一个send方法
// /frameworks/base/core/java/android/os/IMessenger.aidlpackage android.os;import android.os.Message;/** @hide */oneway interface IMessenger { void send(in Message msg);}
IBinder为参数的构造函数和AIDL的很像
public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); }
Messenger和AIDL区别
- 从源码就能看出Messenger就是对AIDL做了个封装,但Messenger只能传递数据,无法调用方法;
- Messenger是以串行方式处理客户端发送的消息,AIDL支持并发处理客户端消息;
更多相关文章
- Nginx系列教程(二)| 一文带你读懂Nginx的正向与反向代理
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Android(安卓)SystemServer学习之二
- Android通过PendingIntent实现消息通知
- android ssl验证、https验证
- Android(安卓)4.2短信小记
- Android(安卓)MQTT使用详解
- Android中EditText的错误消息显示
- Android判断当前系统时间是否在指定时间的范围内(免消息打扰)