❤️ Android IPC 之 Messenger使用 ❤️

举报
帅次 发表于 2021/12/23 00:59:07 2021/12/23
【摘要】     目录 🔥 绑定服务(Bound Services)概述 💥 基础知识 🔥 Messenger 💥 概述 💥 使用 Messenger 步骤 💥 实例(Client到Server数据传递) 🌀 MessengerService.java 🌀 AndroidMainfe...

   

目录

🔥 绑定服务(Bound Services)概述

💥 基础知识

🔥 Messenger

💥 概述

💥 使用 Messenger 步骤

💥 实例(Client到Server数据传递)

🌀 MessengerService.java

🌀 AndroidMainfest.xml

🌀 MainActivity.class

🌀 运行效果如下

💥 实例(Server将数据传回Client)

🌀 MessengerService.java

🌀 MainActivity.java

🌀 运行效果如下

🔥 Messenger 源码

💥 Messenger.java

💥 IMessenger.aidl

💥 new Messenger(Handler handelr)

💥 new Messenger(IBinder target)


     上文讲到了进程间通信(IPC)原理,这里咱们来一起学习一下具体实现。

🔥 绑定服务(Bound Services)概述

        绑定服务是client-server接口中的服务器。它允许组件(例如活动)绑定到服务、发送请求、接收响应和执行进程间通信(IPC)。 绑定服务通常仅在它为另一个应用程序组件提供服务时才存在,并且不会无限期地在后台运行

💥 基础知识

        绑定服务是 Service 类的实现,它允许其他应用程序绑定到它并与之交互。 要为服务提供绑定,你必须实现 onBind() 回调方法。 此方法返回一个 IBinder 对象,该对象定义了客户端可用于与服务交互的编程接口。

🔥 Messenger

💥 概述

        一提到IPC 很多人的反应都是 AIDL,其实如果仅仅是多进程单线程,那么你可以使用 Messenger 为你的服务提供接口。

        使用 Messenger 比使用 AIDL 更简单,因为 Messenger 会将所有对服务的调用排入队列

        对于大多数应用程序,该服务不需要执行多线程,因此使用 Messenger 允许该服务一次处理一个调用。如果你的 服务多线程很重要,那你就要用到ALDL了。

💥 使用 Messenger 步骤

  • 1、该 Service 实现了一个 Handler,该 Handler 接收来自客户端的每次调用的回调。

  • 2、该服务使用 Handler 创建一个 Messenger 对象(它是对 Handler 的引用)。

  • 3、Messenger 创建一个 IBinder,该服务从 onBind() 返回给客户端。

  • 4、客户端使用 IBinder 来实例化 Messenger(引用服务的Handler),客户端使用 Handler 来向服务发送 Message 对象。

  • 5、服务在其 Handler 的 handleMessage() 中接收每个消息。

💥 实例(Client到Server数据传递)

🌀 MessengerService.java


  
  1. public class MessengerService extends Service {
  2.     public static final int MSG_SAY_HELLO = 0;
  3.     //让客户端向IncomingHandler发送消息。
  4.     Messenger messenger = null;
  5.     //当绑定到服务时,我们向我们的Messenger返回一个接口,用于向服务发送消息。
  6.     public IBinder onBind(Intent intent) {
  7.         MLog.e("MessengerService:onBind");
  8.         //创建 Messenger 对象(对 Handler 的引用)
  9.         messenger = new Messenger(new IncomingHander(this));
  10.         //返回支持此Messenger的IBinder。
  11.         return messenger.getBinder();
  12.     }
  13.     //实现了一个 Handler
  14.     static class  IncomingHander extends Handler {
  15.         private Context appliacationContext;
  16.         public IncomingHander(Context context) {
  17.             appliacationContext = context.getApplicationContext();
  18.         }
  19.         @Override
  20.         public void handleMessage(Message msg) {
  21.             switch (msg.what){
  22.                 case MSG_SAY_HELLO:
  23.                     Bundle bundle = msg.getData();
  24.                     String string = bundle.getString("name");
  25.                     //处理来自客户端的消息
  26.                     MLog.e("handleMessage:来自Acitvity的"+string);
  27.                     break;
  28.                 case 1:
  29.                     
  30.                     break;
  31.                 default:
  32.                     super.handleMessage(msg);
  33.             }
  34.         }
  35.     }
  36. }

🌀 AndroidMainfest.xml


  
  1.         <service android:name=".ipc.MessengerService"
  2.             android:process="com.scc.ipc.messengerservice"
  3.             android:exported="true"
  4.             android:enabled="true"/>

        使用 android:process 属性 创建不同进程。

🌀 MainActivity.class


  
  1. public class MainActivity extends ActivityBase implements View.OnClickListener {
  2.     Messenger mService = null;
  3.     Messenger messenger = null;
  4.     private boolean bound;
  5.     private ViewStub v_stud;
  6.     @Override
  7.     public void onCreate(@Nullable Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         setContentView(R.layout.activity_main);
  10.         ...
  11.     }
  12.     ServiceConnection connection = new ServiceConnection() {
  13.         @Override
  14.         public void onServiceConnected(ComponentName name, IBinder service) {
  15.             //从原始 IBinder 创建一个 Messenger,该 IBinder 之前已使用 getBinder 检索到。
  16.             mService = new Messenger(service);
  17.             bound = true;
  18.         }
  19.         @Override
  20.         public void onServiceDisconnected(ComponentName name) {
  21.             bound = false;
  22.         }
  23.     };
  24.     @Override
  25.     public void onClick(View v) {
  26.         switch (v.getId()) {
  27.             case R.id.btn_bind_service:
  28.                 bindService(new Intent(MainActivity.this, MessengerService.class), connection, Context.BIND_AUTO_CREATE);
  29.                 break;
  30.             case R.id.btn_send_msg:
  31.                 Message message = Message.obtain(null, MessengerService.MSG_SAY_HELLO);
  32.                 Bundle bundle = new Bundle();
  33.                 bundle.putString("name","Scc");
  34.                 message.setData(bundle);
  35.                 try {
  36.                     mService.send(message);
  37.                 } catch (RemoteException e) {
  38.                     e.printStackTrace();
  39.                 }
  40.                 break;
  41.         }
  42.     }
  43.     @Override
  44.     protected void onStop() {
  45.         super.onStop();
  46.         if (bound) {
  47.             unbindService(connection);
  48.             bound = false;
  49.         }
  50.     }
  51. }

🌀 运行效果如下

        两个进程也存在着,也完成了进程间的通信,并把数据传递过去了。

💥 实例(Server将数据传回Client)

        我不仅想将消息传递给 Server ,还想让 Server 将数据处理后传会Client。

🌀 MessengerService.java


  
  1. public class MessengerService extends Service {
  2.     /** 用于显示和隐藏我们的通知。 */
  3.     ArrayList<Messenger> mClients = new ArrayList<Messenger>();
  4.     /** 保存客户端设置的最后一个值。 */
  5.     int mValue = 0;
  6.     /**
  7.      * 数组中添加 Messenger (来自客户端)。
  8.      * Message 的 replyTo 字段必须是应该发送回调的客户端的 Messenger。
  9.      */
  10.     public static final int MSG_REGISTER_CLIENT = 1;
  11.     /**
  12.      * 数组中删除 Messenger (来自客户端)。
  13.      * Message 的 replyTo 字段必须是之前用 MSG_REGISTER_CLIENT 给出的客户端的 Messenger。
  14.      */
  15.     public static final int MSG_UNREGISTER_CLIENT = 2;
  16.     /**
  17.      * 用于设置新值。
  18.      * 这可以发送到服务以提供新值,并将由服务发送给具有新值的任何注册客户端。
  19.      */
  20.     public static final int MSG_SET_VALUE = 3;
  21.     //让客户端向IncomingHandler发送消息。
  22.     Messenger messenger = null;
  23.     //当绑定到服务时,我们向我们的Messenger返回一个接口,用于向服务发送消息。
  24.     public IBinder onBind(Intent intent) {
  25.         MLog.e("MessengerService-onBind");
  26.         //创建 Messenger 对象(对 Handler 的引用)
  27.         messenger = new Messenger(new IncomingHander(this));
  28.         //返回支持此Messenger的IBinder。
  29.         return messenger.getBinder();
  30.     }
  31.     //实现了一个 Handler
  32.     class  IncomingHander extends Handler {
  33.         private Context appliacationContext;
  34.         public IncomingHander(Context context) {
  35.             appliacationContext = context.getApplicationContext();
  36.         }
  37.         @Override
  38.         public void handleMessage(Message msg) {
  39.             switch (msg.what){
  40.                 case MSG_REGISTER_CLIENT:
  41.                     mClients.add(msg.replyTo);
  42.                     break;
  43.                 case MSG_UNREGISTER_CLIENT:
  44.                     mClients.remove(msg.replyTo);
  45.                     break;
  46.                 case MSG_SET_VALUE:
  47.                     mValue = msg.arg1;
  48.                     for (int i=mClients.size()-1; i>=0; i--) {
  49.                         try {
  50.                             mClients.get(i).send(Message.obtain(null,
  51.                                     MSG_SET_VALUE, mValue, 0));
  52.                         } catch (RemoteException e) {
  53.                             // 客户端没了。 从列表中删除它;
  54.                             //从后往前安全,从前往后遍历数组越界。
  55.                             mClients.remove(i);
  56.                         }
  57.                     }
  58.                 default:
  59.                     super.handleMessage(msg);
  60.             }
  61.         }
  62.     }
  63. }

🌀 MainActivity.java


  
  1. public class MainActivity extends ActivityBase implements View.OnClickListener {
  2.     Messenger mService = null;
  3.     Messenger messenger = null;
  4.     private boolean bound;
  5.     private ViewStub v_stud;
  6.     @Override
  7.     public void onCreate(@Nullable Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         setContentView(R.layout.activity_main);
  10.         ...
  11.     }
  12.     ServiceConnection connection = new ServiceConnection() {
  13.         @Override
  14.         public void onServiceConnected(ComponentName name, IBinder service) {
  15.             //从原始 IBinder 创建一个 Messenger,该 IBinder 之前已使用 getBinder 检索到。
  16.             mService = new Messenger(service);
  17.             bound = true;
  18.         }
  19.         @Override
  20.         public void onServiceDisconnected(ComponentName name) {
  21.             bound = false;
  22.         }
  23.     };
  24.     static class ReturnHander extends Handler {
  25.         @Override
  26.         public void handleMessage(Message msg) {
  27.             switch (msg.what) {
  28.                 case MessengerService.MSG_SET_VALUE:
  29.                     //我要起飞:此处处理
  30.                     MLog.e("Received from service: " + msg.arg1);
  31.                     break;
  32.                 default:
  33.                     super.handleMessage(msg);
  34.             }
  35.         }
  36.     }
  37.     @Override
  38.     public void onClick(View v) {
  39.         switch (v.getId()) {
  40.             case R.id.btn_bind_service:
  41.                 bindService(new Intent(MainActivity.this, MessengerService.class), connection, Context.BIND_AUTO_CREATE);
  42.                 break;
  43.             case R.id.btn_send_msg:
  44.                 try {
  45.                     mMessenger = new Messenger(new ReturnHander());
  46.                     Message msg = Message.obtain(null,
  47.                             MessengerService.MSG_REGISTER_CLIENT);
  48.                     msg.replyTo = mMessenger;
  49.                     //先发一则消息添加Messenger:msg.replyTo = mMessenger;
  50.                     mService.send(msg);
  51.                     // Give it some value as an example.
  52.                     msg = Message.obtain(null,
  53.                             MessengerService.MSG_SET_VALUE, this.hashCode(), 0);
  54.                     //传入的arg1值:this.hashCode()
  55.                     mService.send(msg);
  56.                 } catch (RemoteException e) {
  57.                     e.printStackTrace();
  58.                 }
  59.                 break;
  60.         }
  61.     }
  62.     @Override
  63.     protected void onStop() {
  64.         super.onStop();
  65.         if (bound) {
  66.             unbindService(connection);
  67.             bound = false;
  68.         }
  69.     }
  70. }

🌀 运行效果如下

        我们在MainActivity 的 Handler.sendMessger()中接收到了来自 MesengerService 的消息 。

        本次 Messenger 进程间通信齐活,这只是个简单的Demo。最后咱们看一波源码。

🔥 Messenger 源码

💥 Messenger.java


  
  1. public final class Messenger implements Parcelable {
  2.     private final IMessenger mTarget;
  3.     public Messenger(Handler target) {
  4.         mTarget = target.getIMessenger();
  5.     }
  6.     public void send(Message message) throws RemoteException {
  7.         mTarget.send(message);
  8.     }
  9.     public IBinder getBinder() {
  10.         return mTarget.asBinder();
  11.     }
  12.     ...
  13.     public Messenger(IBinder target) {
  14.         mTarget = IMessenger.Stub.asInterface(target);
  15.     }
  16. }

然后你会发现 只要代码还是在 IMessenger 里面,咱们去找找。

💥 IMessenger.aidl


  
  1. package android.os;
  2. import android.os.Message;
  3. /** @hide */
  4. oneway interface IMessenger {
  5.     void send(in Message msg);
  6. }

💥 new Messenger(Handler handelr)

        这里其实是用Handler 调用 getIMessenger() 。咱们去Handler.class里面转转。


  
  1.     @UnsupportedAppUsage
  2.     final IMessenger getIMessenger() {
  3.         synchronized (mQueue) {
  4.             if (mMessenger != null) {
  5.                 return mMessenger;
  6.             }
  7.             mMessenger = new MessengerImpl();
  8.             return mMessenger;
  9.         }
  10.     }
  11.     //创建了Messenger实现类
  12.     private final class MessengerImpl extends IMessenger.Stub {
  13.         public void send(Message msg) {
  14.             msg.sendingUid = Binder.getCallingUid();
  15.             //Messenger调用send()方法,通过Handler发送消息。
  16.             //然后在服务端通过Handler的handleMessge(msg)接收这个消息。
  17.             Handler.this.sendMessage(msg);
  18.         }
  19.     }

💥 new Messenger(IBinder target)


  
  1. package android.os;
  2. /** @hide */
  3. public interface IMessenger extends android.os.IInterface
  4. {
  5.   /** Default implementation for IMessenger. */
  6.   public static class Default implements android.os.IMessenger
  7.   {
  8.     @Override public void send(android.os.Message msg) throws android.os.RemoteException
  9.     {
  10.     }
  11.     @Override
  12.     public android.os.IBinder asBinder() {
  13.       return null;
  14.     }
  15.   }
  16.   /** Local-side IPC implementation stub class. */
  17.   public static abstract class Stub extends android.os.Binder implements android.os.IMessenger
  18.   {
  19.     /** Construct the stub at attach it to the interface. */
  20.     public Stub()
  21.     {
  22.       this.attachInterface(this, DESCRIPTOR);
  23.     }
  24.     /**
  25.      * Cast an IBinder object into an android.os.IMessenger interface,
  26.      * generating a proxy if needed.
  27.      */
  28.     public static android.os.IMessenger asInterface(android.os.IBinder obj)
  29.     {
  30.       if ((obj==null)) {
  31.         return null;
  32.       }
  33.       android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
  34.       //判断是否在同一进程。
  35.       if (((iin!=null)&&(iin instanceof android.os.IMessenger))) {
  36.         //同一进程
  37.         return ((android.os.IMessenger)iin);
  38.       }
  39.       //代理对象
  40.       return new android.os.IMessenger.Stub.Proxy(obj);
  41.     }
  42.     @Override public android.os.IBinder asBinder()
  43.     {
  44.       return this;
  45.     }
  46.     ...
  47.   }
  48.   public void send(android.os.Message msg) throws android.os.RemoteException;
  49. }

        看了上面代码你会发现这不就是个aidl吗? 什么是aidl,咱们下一篇继续讲到。

文章来源: shuaici.blog.csdn.net,作者:帅次,版权归原作者所有,如需转载,请联系作者。

原文链接:shuaici.blog.csdn.net/article/details/120911760

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。