一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
一.Messenger简介
与AIDL进程间通信作用一样,Messenger是基于Message对象进行跨进程通信的,类似于Handler发送消息实现子线程和UI线程进行通信,此外,还支持记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信。 普通的进程间通信,需要服务端自己提供AIDL接口文件,然后本地实现Stub内方法,客户端需要引入方可进行通信;Messenger是系统提供统一的AIDL接口文件,并且由Handler来实现Stub内方法,服务端在Handler内处理即可,客户端不需要引入,直接可以通信;
二.Messenger实现流程
a.服务端实现
- 创建一个Handler对象,并实现handleMessage方法,用于接收来自客户端的消息并作处理;
- 创建一个Messenger(送信人),封装Handler;
- 用Messenger的getBinder()方法获取一个IBinder对象,通过onBind返回给客户端; 代码如下:
public class MyService extends Service {
private static final String TAG = MyService.class.getSimpleName();
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private MessengerHandler mHandler = new MessengerHandler();
private Messenger mMessenger = new Messenger(mHandler);
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//取出客户端的消息内容
Bundle bundle = msg.getData();
String clientMsg = bundle.getString("client");
Log.i(TAG,"来自客户端的消息:"+clientMsg);
//新建一个Message对象,作为回复客户端的对象
Message message = Message.obtain();
Bundle bundle1 = new Bundle();
bundle1.putString("server","已收到消息");
message.setData(bundle1);
try {
msg.replyTo.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
服务端接受到客户端的消息,其实与线程间通信一样,也是在handleMessage方法中进行处理;
如果服务端需要回复客户端,则需要获取到客户端携带过来的Messenger对象(即msg.replyTo),通过msg.replyTo.send()给客户端发送信息。
b.客户端实现
- 绑定服务,创建ServiceConnection并在其中使用IBinder将Messenger实例化;
- 使用Messenger向服务端发送消息;
- 接收服务端发送过来的message;
- 解绑服务;
实现如下:
public class MyActivity extends Activity implements View.OnClickListener {
private static final String TAG = MyActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bindService = findViewById(R.id.bindService);
Button unBindService = findViewById(R.id.unBindService);
bindService.setOnClickListener(this);
unBindService.setOnClickListener(this);
}
public void onClick(View view) {
switch (view.getId()){
case R.id.bindService:
Intent intent = new Intent();
intent.setAction("com.hly.learn.server.action");
bindService(intent,mConnection,BIND_AUTO_CREATE);
break;
case R.id.unBindService:
unbindService(mConnection);
break;
default:
break;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取服务端关联的Messenger对象
Messenger mService = new Messenger(service);
//创建Message对象
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("client","hello");
message.setData(bundle);
try {
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
}
}
客户端在绑定服务之后,在ServiceConnection中通过IBinder得到Messenger对象(mService),然后用mService的send方法把Message作为形参发送给服务端。