使用messenger完成进程间通信
messenger可以翻译为信使,故名思议他可以在进程间传递message,我们可以将数据封装在message中通过messenger在进程间完成传递,messenger是一种轻量级的IPC(进程间通信,跨进程通信)方案,是AIDL的上层封装
好处:
使用简单,方便调用,不存在并发,因为他是串行方式处理客户端数据
弊端:
串行方式处理客户端数据,一次只会处理一个请求,如果有大量的并发请求,他也只会一个一个处理,基本只能用于传递消息,无法通过跨进程调用服务端的方法
用处:
一般用于传递消息
使用:
分为服务端和客户端来使用,下面使用Demo说明
1.服务端
首先我们创建一个service,用于连接客户端,并创建一个handler和Messenger关联,并在onBind方法中返回这个Messenger的底层iBinder即可,这里Messenger的作用就是将客户端的数据交给handler来处理,注意服务端是要运行在独立的进程中,也就是服务的service要声明process属性,这样等同于模仿两个应用,完成跨进程通信
2.客户端
客户端需要绑定服务端的service,通过绑定成功后的iBinder对象创建messenger,通过这个messenger就可以向服务端发送数据了,如果需要服务端返回数据给客户端,那么就需要在客户端也创建一个Handler和messenger关联 并且将这个messenger通过message的replyTo参数传递给服务端,服务端通过这个replyTo参数就可以拿到客户端的messenger了就可以返回数据了,下面看下代码一目“鸟”然
服务端代码:
/*ipc之messenger通信 服务端 运行在独立进程中*/
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
private static class messengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_FROM_CLIENT:
Log.d(TAG, "handleMessage : " + msg.getData().getString("msg"));
//replyTo获取的是客户端message设置的messenger,这个messenger和客户端的handler关联了 所以客户端是可以收到服务端返回的消息
Messenger client = msg.replyTo;
//messenger只能发送message 当然他们都实现了Parcelable 所以可以在进程间传递
Message replyMessage = Message.obtain(null, Constants.MSG_FROM_SERVICE);
//bundle可以存放比较多的数据类型且实现了Parcelable message的object非系统的Parcelable无法通过Object来传输,所以实用性比较低
Bundle data = new Bundle();
data.putString("msg", "黄河黄河我是长江");
replyMessage.setData(data);
try {
client.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
//将mseeengerHandler和Messenger关联起来 这样就可以收到mMessenger发送过来的数据
private final Messenger mMessenger = new Messenger(new messengerHandler());
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
服务端的service需要运行在独立的进程中,所以我们在清单中声明一下android:process=”:remote”
客户端代码
/*ipc之messenger通信 客户端*/
public class MessengerActivity extends AppCompatActivity {
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
private static final String TAG = "MessengerService";
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_FROM_SERVICE:
Log.d(TAG, "handleMessage : " + msg.getData().getString("msg"));
break;
default:
super.handleMessage(msg);
break;
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
Message msg = Message.obtain(null, Constants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "长江长江我是黄河");
msg.setData(data);
//如果不把mGetReplyMessenger赋值给replyTo 那么服务端就会获取空的messenger 也就无法返回数据
msg.replyTo = mGetReplyMessenger;
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private Messenger mService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//绑定服务端的service
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
最后看下客户端和服务端的交互log
08-22 09:17:01.797 4219-4219/? D/MessengerService: handleMessage : 长江长江我是黄河
08-22 09:17:01.897 4206-4206/? D/MessengerService: handleMessage : 黄河黄河我是长江