之前ipc数据传递相关文章: ipc数据传递方式之一 aidl
Messenger可以翻译为信使 顾名思义 它可以在不同进程之间传递Message对象,我们在Message中放置我们要传递的数据,就可以进行进程间的数据传递了
看一下Messenger的构造方法 很明显Messenger的底层是由aidl实现的 使用Messenger进行进程间通讯也更加方便
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target){
mTarget = IMessenger.Stud.asInterface(target);
}
来一张图理解下Messenger的工作原理
Messenger的使用
首先创建一个服务并在清单文件中注册以及指定其在新进程中运行
<service android:name=".MessengerService" android:process=":remote"/>
然后分别创建服务端和客户端
服务端的代码:
public class MessengerService extends Service {
private static final String TAG = "MessengerServic";
//MessengerHandler继承Handler 用来处理客户端发送过来的message
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
//打印接收客户端发送过来的消息
Log.d(TAG, "msg.getData():" + msg.getData().getString("msg"));
//服务端收到消息后向客户端回复 服务端带上replyto参数代表回复
//客户端会找到同样标记replyTo参数的Messenger
Messenger toclient = msg.replyTo;
Message message = Message.obtain(null,2);
Bundle bundle = new Bundle();
bundle.putString("reply" , "服务端向你回复");
message.setData(bundle);
try {
toclient.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
private final Messenger messenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
//Messenger.getBinder方法返回一个Binder对象
return messenger.getBinder();
}
}
客户端的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button toservicebtn;
private Messenger toServermessenger;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//根据服务端返回的ibinder对象创建messenger对象
toServermessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//客户端接收服务端的回复
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 2:
//打印服务端的回复
Log.d("MessengerHandler", msg.getData().getString("reply"));
break;
}
}
}
private Messenger getReplyMessenger = new Messenger(new MessengerHandler());
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//绑定服务
Intent intent = new Intent(this,MessengerService.class);
bindService(intent,connection,BIND_AUTO_CREATE);
}
private void initView() {
toservicebtn = (Button) findViewById(R.id.toservicebtn);
toservicebtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.toservicebtn:
//客户端向服务端发送消息
//第二个参数是msgwhat 用作handlermessage回调中的switch判断
Message msg = Message.obtain(null,1);
Bundle data = new Bundle();
data.putString("msg","this is client");
msg.setData(data);
//很关键的一点:当客户端发送消息的时候 需要把接收服务端回复的Messenger
//通过Message的replyTo参数传递给服务端 这样服务端知道回复给谁
msg.replyTo = getReplyMessenger;
try {
//Messenger信使把message发走
toServermessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
acticity中有个按钮 在点击事件中向服务端发送消息,每次发送完成之后 服务端会向客户端回复
这样Messenger进程间通讯就完成了