您的位置:首页 > 移动开发 > Android开发

android-----IPC进程间通信之Messenger

2016-07-15 12:02 441 查看
        Messenger是android为我们提供的可以在不同进程间传递Message的信使,他是对AIDL的封装,为此,我总结了他的几个特点:

        (1):哪里需要回送消息就需要在哪里创建一个Handler,因为使用Messenger实际处理消息的是Handler;

        (2):Messenger一次只能处理一个请求,因此不需要我们考虑线程同步的问题,原因很简单,因为服务端处理请求使用的是

Handler实现的,而Handler底层是使用MessageQueue队列存放消息的,MessageQueue是按照顺序来处理的消息的,这也就

造成了Messenger不适合于并发处理的特点;

        (3):Messenger只能向服务端传递Message数据,并不能调用服务端的方法;

        (4):Messenger的底层是用AIDL实现的;

        (5):还有一点需要注意的是Message中的object字段是不能用来跨进程传递我们自己定义的Parcel对象的,仅在同一进程

中实用;

        (6):如果服务端在收到消息之后需要回复客户端的话,则需要用到Message的replyTo字段,该字段封装了客户端通过自己

的Handler创建的Messenger对象;

        可能你会觉得这个总结有点晦涩,没事我们来看看Messenger类里面的重要方法就能看出点端倪来:

        先来看看他的两个构造函数:

public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
        第一个构造方法主要用于服务端创建Messenger对象,传入的参数是Handler对象;

        第二个构造方法主要用于客户端创建Messenger对象,传入的参数服务端回传回来的Binder对象,其实我们可以把客户端通过这个构造方法创建的Messenger对象看做是服务端Messenger对象的引用,那么接下来在客户端使用此Messenger对象进行消息发送的时候实际上执行的就是该引用的handleMessage方法,也就执行了服务端的handleMessage方法了;

        当然,因为Messenger实现了Parcelable序列化接口,所以我们也看到了describeContents、writeToParcel等关于序列化的方法;

        接下来就是getBinder方法了:

public IBinder getBinder() {
return mTarget.asBinder();
}
        该方法用于服务端通过Messenger获得Binder对象,并且通过onBind方法返回给客户端,也就是客户端中ServiceConnection对象中的onServiceConnected中的第二个参数对应的值了;

public ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
}
        在Messenger中还有一个send方法,该方法主要用于客户端通过Messenger对象发送消息给服务端,当然如果服务端想要回传消息给客户端的话,也可以使用该方法:

public void send(Message message) throws RemoteException {
mTarget.send(message);
}
        以上就是Messenger在进程间通信中用到的方法,接下来通过一个实例来真正看看Messenger是怎么用的:

        服务端:

public class MessengerService extends Service {

//创建一个Handler对象,用来处理客户端发送过来的消息,同时使用它创建一个Messenger对象,在onBind方法中通过Messenger对象获得Binder对象返回
private class MessengerHandler extends Handler
{
public Messenger clientMessenger;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
System.out.println("服务端收到的消息为:  name--->"+msg.getData().getString("name")+" age--->"+msg.getData().getInt("age"));
//服务端获取到客户端的Messenger对象
clientMessenger = msg.replyTo;
//通过Bundler封装回传给客户端的信息
Bundle bundle = new Bundle();
bundle.putString("message", "消息已经收到了......");
//创建一个封装有Bundle内容的Message
Message message = Message.obtain();
message.what = 0;
message.setData(bundle);
//发送消息给客户端
try {
clientMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
super.handleMessage(msg);
}
}

//通过Handler对象来创建Messenger对象
Messenger messenger = new Messenger(new MessengerHandler());

@Override
public IBinder onBind(Intent arg0) {
//通过Messenger对象获得Binder对象返回给客户端
return messenger.getBinder();
}
}
        客户端:

public class MainActivity extends Activity implements OnClickListener{

public Button mButton;
public Messenger messenger;
public Messenger clientMessenger;

//创建客户端自己的Handler对象,用于处理服务端对客户端的响应信息
private static class MessageHandler extends Handler
{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
//获得服务端回传的数据
System.out.println("服务端回传的数据:  "+msg.getData().getString("message"));
break;

default:
break;
}
super.handleMessage(msg);
}
}

public ServiceConnection connection = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName arg0) {

}

@Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
//通过Binder对象获得Messenger对象
messenger = new Messenger(service);
//接下来就可以通过Messenger对象来发送消息给服务端了
//首先将要传递给远程服务端的数据封装到Bundle里面
Bundle bundle = new Bundle();
bundle.putString("name", "张三");
bundle.putInt("age", 24);
//获得一个Message对象,将Bundle对象添加到Message对象里面
Message message = Message.obtain();
message.what = 0;
message.setData(bundle);
//客户端需要将封装有自身Handler对象的Messenger对象通过Message的replyTo字段传递到服务端
//通过Messenger对象发送Message对象给服务端
message.replyTo = clientMessenger;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.button);
mButton.setOnClickListener(this);
//创建客户端自身的Messenger对象
clientMessenger = new Messenger(new MessageHandler());
}
@Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, MessengerService.class);
bindService(intent, connection, BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
//解除绑定
unbindService(connection);
super.onDestroy();
}
}
        至于代码的具体讲解,在注释中已经全部表现出来了,我就不具体说了,最后不要忘记将服务开启在另一个进程中来测试了:

<service
android:name="com.hzw.multiprocess.MessengerService"
android:process=":remote">
</service>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息