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类里面的重要方法就能看出点端倪来:
先来看看他的两个构造函数:
第二个构造方法主要用于客户端创建Messenger对象,传入的参数服务端回传回来的Binder对象,其实我们可以把客户端通过这个构造方法创建的Messenger对象看做是服务端Messenger对象的引用,那么接下来在客户端使用此Messenger对象进行消息发送的时候实际上执行的就是该引用的handleMessage方法,也就执行了服务端的handleMessage方法了;
当然,因为Messenger实现了Parcelable序列化接口,所以我们也看到了describeContents、writeToParcel等关于序列化的方法;
接下来就是getBinder方法了:
服务端:
(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>
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories