读书有感突然想写一篇关于Messager的博客,记录一下笔者对android进程通信Messenger的使用的梳理
进程间通信最经典的就是client和Service之间的通信了,那么首先我们就来创建一个这样的模型来进行Messenger的学习和梳理
创建一个android工程,创建一个MainActivity.java 和一个Service,并在清单文件中配置Service运行在一个独立的remote进程中清单文件配置代码如下:
<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true"
android:process=":remote">
</service>
下面就来看一下我们在服务里具体做了什么?我们在服务里做了三件事
1.创建一个Handler对象
2.创建Messager信使对象,并将服务的handler交给Messager信使
3.通过IBind的onBind(Intent intent )方法将服务的Messenger信使返回出去
具体代码如下
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
private final Messenger messenger = new Messenger(new MessengerHandler());
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
// throw new UnsupportedOperationException("Not yet implemented");
}
好了,接下来我们来看一下client这边做了什么操作
客户端这边做了五件事
1.绑定服务
2.在服务的onServiceConnection里面拿到服务那边返回的Messenger信使对象
3.创建一个消息Message
4.创建一个客户端的Messenger并把他交给Message
5.然后让服务那边的Messenger把消息发送给服务端
具体代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//通过Intent绑定服务
Intent intent = new Intent(this, MessengerService.class);
myConnection = new MyConnection();
//第一步:绑定服务
bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
startService(intent);
}
private class MyConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//第二步:获得服务那边返回出来的Messenger
mMessengerFromService = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
//第三步:创建一个客户端的信使ClientMessenger
private Messenger ClientMessenger = new Messenger(new ClientHandler());
public void send(View view){
Log.d(TAG,"向服务发送消息");
//第四步:创建一个消息对象
Message message = Message.obtain(null,Constant.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","hello,this is a message from client");
message.setData(data);
//第五步:将客户端的信使放到消息上
message.replyTo = ClientMessenger;
try {
//第六步:通过服务端的信使将消息发送给服务端
mMessengerFromService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(myConnection);
}
通过上面的send方法,我们通过服务那边的信使给服务发送了一条消息,这消息上携带了消息的内容和客户端的信使
下面我们就到服务那边来处理一下这个消息,服务的信使绑定了服务那边的ServiceHandler,所以我们通过他来处理消息
private static class ServiceHandler extends Handler{
@Override
public void handleMessage(Message msg) {
//第一步:获得客户端那边的信使clientMessenger;
mClientMessenger = msg.replyTo;
switch (msg.what){
//第二步:处理客户端发来的消息内容
case Constant.MSG_FROM_CLIENT:
Log.d(TAG,"receive message from client"+ msg.getData().getString("msg"));
//第三步:通过客户端的信使给客户端发一个消息;
sendBackToClient(Constant.MSG_FROM_SERVICE);
break;
default:
super.handleMessage(msg);
}
}
//通过客户端的信使给客户端发消息
private void sendBackToClient(int what) {
try {
if(mClientMessenger == null)
return;
Message message = Message.obtain(null,what);
Bundle bundle = new Bundle();
bundle.putString("msg","你好client,这是来自服务端的问候");
message.setData(bundle);
mClientMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
OK到目前为止,流程全部走完
总结如下:
客户端:
1.client通过绑定服务获得服务那边的ServiceMessenger服务信使
2.client创建一个消息,和一个clientMessenger客户端的信使,并将客户端的信使绑定到消息上
3.让服务的信使吧客户端创建的消息发送给服务端
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------
服务端:
1.创建一个服务端的ServiceMessenger,并在客户端和服务端绑定的时候将他通过IBinder返回给客户端
(客户端就是通过这个服务端的信使来给服务端发消息的)
2.使用ServiceMessenger绑定的ServiceHandler来处理客户端发来的消息:
a.首先获得客户端消息携带的一个信使(就是通过客户端的这个ClientMessenger来给客户端发消息);
b.获得客户端发来消息的详细内容,并通过获得的客户端的信使,来给客户端一个回音(客户端的信使绑定的客户端的ClientHandler来处理服务端发的消息)
到这里总结完毕:
各位看官有什么不清晰的地方,请给留言,大家一起交流谢谢!