Messenger实现进程间低并发即时通信
Messenger是一种轻量级的IPC,底层实现是AIDL,即可认为Binder。通过在Message中携带Bundle进而实现进程之间传递数据。由于Messenger一次只能处理一个请求,因此服务端们不用考虑线程同步问题。
一,我们在服务端创建一个Handler用于接受来自客户端消息,并以此Handler创建Messenger,我们将这个Messenger的Binder对象通过onBinde( )方法返回给客户端;在客户端链接服务的onServiceConnected( )方法中取得Binder对象,转化为Messenger,即可发送消息给服务端。
二,我们在客户端创建一个Handler用于接受来自服务端的消息,同样需要以此Handler创建一个Messenger并将它返回给服务端用于发送消息,怎么返回的呢?在客户端链接服务的onServiceConnected( )方法中,当客户端向服务端发送消息时携带上刚刚创建的Messenger对象,message.replyTo = 刚刚创建的Messenger对象,而在服务端的Handler中我们可以从msg中取出来自客户端的消息和Messenger对象,Messenger reply = msg.replyTo;以此向客户端发送消息。
三,优点:功能一般,支持一对多串行通信,支持实时通信
缺点:不能很好处理高并发,不支持远程RPC,只能传输Bundle支持的数据类型。
适用场景:低并发一对多即时通信,无RPC请求,或者无需返回结果的RPC请求。
1.服务端
public class MessengerService extends Service {
public static final int SERVICE_REPLY_WHAT = 100;
public static final String SERVICE_REPLY_KEY = "service_reply_key";
//将此Messenger对象传递给客户端,以此向服务端发送消息
private Messenger mMessenger = new Messenger(new ServiceHandler());
public MessengerService() {
}
private class ServiceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
//收到来自客户端的指令并进行回复
case MainActivity.MAIN_SEND_WHAT:
String msgStr = msg.getData().getString(MainActivity.MAIN_SEND_KEY);
Toast.makeText(MessengerService.this, msgStr, Toast.LENGTH_SHORT).show();
//取出来自客户端的Messemger对象,以此想客户端发送消息
Messenger reply = msg.replyTo;
Message message = Message.obtain(null, SERVICE_REPLY_WHAT);
Bundle bundle = new Bundle();
bundle.putString(SERVICE_REPLY_KEY, "收到来自客户端消息,服务端很高兴,这是回信。");
message.setData(bundle);
try {
reply.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
@Override
public IBinder onBind(Intent intent) {
//将服务端Handler构造的Messenger的Binger对象传送给客户端
return mMessenger.getBinder();
}
}
2.客户端
public class MainActivity extends AppCompatActivity {
public static final int MAIN_SEND_WHAT = 101;
public static final String MAIN_SEND_KEY = "main_send_key";
//用来自service的IBinder对象构造Messenger,向Service端发送消息
private Messenger mMessenger;
//以客户端Handler构造Messenger并传递给服务端,服务端以此向客户端发送消息
private Messenger mSendMessenger = new Messenger(new mainHandler());
private class mainHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
//收到来自服务端的回信
case MessengerService.SERVICE_REPLY_WHAT:
String msgStr = msg.getData().getString(MessengerService.SERVICE_REPLY_KEY);
Toast.makeText(MainActivity.this, msgStr, Toast.LENGTH_SHORT).show();
default:
super.handleMessage(msg);
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this,MessengerService.class);
//绑定服务
bindService(intent,mConnection,BIND_AUTO_CREATE);
}
//服务连接
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder Binder) {
//取出来自服务端的Binder对象构建Messenger,以此向服务端发送消息
mMessenger = new Messenger(Binder);
Message message = Message.obtain(null,MAIN_SEND_WHAT);
Bundle bundle = new Bundle();
bundle.putString(MAIN_SEND_KEY,"你好Service,这是来自客户端的问候。");
message.setData(bundle);
//将客户端Handler构造的Messenger传给服务端,服务端以此Messenger向客户端发送消息
message.replyTo = mSendMessenger;
try {
mMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}