当前位置:   article > 正文

Android开发——进程间通信之Messenger_android messenger c++

android messenger c++

0.  前言

不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPCInter-Process Communication)即进程间通信。首先线程和进程是很不同的概念,线程是CPU调用的最小单元,进程一般在PC和移动设备上指一个程序或者一个应用,一个进程可以包含多个线程。

IPC方式有很多,在Android中常用的IPC方式包括Bundle、文件、MessengerAIDLContentProviderSocket等方式。

本篇主要讲解使用Messenger的方式。本文原创,转载请注明出处为SEU_Calvin的博客

 

1.  Messenger

Messenger是系统为我们封装好的一套IPC方案,它的底层是基于AIDLHandler。使用Messenger可以在不同进程中传递Message对象,并在Message中放入我们需要传递的数据,就可以实现数据的进程间通信了。

Messenger的构造方法如下所示:

  1. public Messenger(Handler target) {
  2. mTarget = target.getIMessenger();
  3. }
  4. public Messenger(IBinder target) {
  5. mTarget = IMessenger.Stub.asInterface(target);
  6. }

既然是进程间通信吗,那么直接看代码好了,先看服务器端所在进程的代码:

  1. public class MessengerService extends Service {
  2. private static final String Messenger_TAG = "Messenger";
  3. private static class ServerMessengerHandler extends Handler {
  4. @Override
  5. public void handleMessage(Message msg) {
  6. switch (msg.what) {
  7. case 0:
  8. // 接收到客户端的信息
  9. Log.i(Messenger_TAG, msg.getData().getString("client-data") + " " + Thread.currentThread().toString());
  10. // 返回信息给客户端
  11. Messenger replyMessenger = msg.replyTo;
  12. Message message = Message.obtain();
  13. message.what = 1;
  14. Bundle data = new Bundle();
  15. data.putString("server-data", "hello client, I have received your message! ");
  16. message.setData(data);
  17. try {
  18. replyMessenger.send(message);
  19. } catch (RemoteException e) {
  20. e.printStackTrace();
  21. }
  22. break;
  23. default:
  24. super.handleMessage(msg);
  25. }
  26. }
  27. }
  28. // 服务端Messenger
  29. private Messenger serverMessenger = new Messenger(new ServerMessengerHandler());
  30. @Override
  31. public IBinder onBind(Intent intent) {
  32. return serverMessenger.getBinder();
  33. }
  34. }

服务器端创建一个Service来处理客户端的连接请求,同时创建一个Handler并以此为参数实例一个Messenger来接收客户端Messenger发来的message,最后在onBind方法返回这个MessengerBinder。在handleMessage()中不仅展示了客户端传来的信息,还使用Messenger replyMessenger =msg.replyTo获取客户端Messenger对象,装载数据后通过replyMessenger.send(message)返回message信息给客户端。完成了回复的功能。最后看一个客户端的代码:

  1. public class MainActivity extends AppCompatActivity {
  2. private static final String Messenger_TAG = "Messenger";
  3. private Messenger clientMessenger;
  4. private Button button;
  5. // 接收服务端返回信息的Messenger
  6. private Messenger replyMessenger = new Messenger(new ClientMessengerHandler());
  7. private static class ClientMessengerHandler extends Handler {
  8. @Override
  9. public void handleMessage(Message msg) {
  10. switch (msg.what) {
  11. case 1:
  12. // 接收到服务端返回的信息
  13. Log.i(Messenger_TAG, msg.getData().getString("server-data") + " " + Thread.currentThread().toString());
  14. break;
  15. default:
  16. super.handleMessage(msg);
  17. }
  18. }
  19. }
  20. private ServiceConnection serviceConnection = new ServiceConnection() {
  21. @Override
  22. public void onServiceConnected(ComponentName name, IBinder service) {
  23. clientMessenger = new Messenger(service);
  24. }
  25. @Override
  26. public void onServiceDisconnected(ComponentName name) {
  27. }
  28. };
  29. @Override
  30. protected void onCreate(Bundle savedInstanceState) {
  31. super.onCreate(savedInstanceState);
  32. setContentView(R.layout.activity_main);
  33. button = (Button) findViewById(R.id.messenger);
  34. // bind服务端Service
  35. Intent intent = new Intent(this, MessengerService.class);
  36. bindService(intent, serviceConnection, BIND_AUTO_CREATE);
  37. button.setOnClickListener(new View.OnClickListener() {
  38. @Override
  39. public void onClick(View v) {
  40. // 发送消息到服务端
  41. Message message = Message.obtain();
  42. message.what = 0;
  43. Bundle data = new Bundle();
  44. data.putString("client-data", "hello server");
  45. message.setData(data);
  46. // 指定接收服务端返回信息的Messenger
  47. message.replyTo = replyMessenger;
  48. try {
  49. clientMessenger.send(message);
  50. } catch (RemoteException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. });
  55. }
  56. @Override
  57. protected void onDestroy() {
  58. super.onDestroy();
  59. unbindService(serviceConnection);
  60. }
  61. }

首先在onCreate()中使用bindService()绑定服务,绑定成功后回调onServiceConnected()并在其中获得服务器返回的Binder对象,并通过这个Binder对象创建出Messenger对象clientMessenger。这里需要注意的是,与服务的连接意外中断时(例如当服务崩溃或被终止时)会回调onServiceDisconnected()方法。而当客户端主动取消绑定时,则不会调用该方法

点击按钮后clientMessenger.send(message)向服务器端发送消息,注意这里message消息通过replyTo生成了replyMessenger实例,即接收服务端返回信息的Messenger,并在其构造参数中自定义了接收并处理服务端返回信息的Handler

点击按钮后结果如下,在两个进程中分别打印出信息:

 

这样整个客户端和服务端的跨进程通信过程就使用Messenger完成了。参考源码点击下载

Messenger 会在单一线程中创建包含所有客户端请求的队列,如果你想让服务同时处理多个请求,则可直接使用 AIDL。在此情况下,你的服务必须具备多线程处理能力,并采用线程安全式设计

因此AIDL和经过封装的Messenger相比,最大的不同就是AIDL具备多线程处理能力,下一篇将介绍使用AIDL进行进程间通信的介绍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/122579
推荐阅读
相关标签
  

闽ICP备14008679号