上文讲到了进程间通信(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
public class MessengerService extends Service { public static final int MSG_SAY_HELLO = 0; //让客户端向IncomingHandler发送消息。 Messenger messenger = null; //当绑定到服务时,我们向我们的Messenger返回一个接口,用于向服务发送消息。 public IBinder onBind(Intent intent) { MLog.e("MessengerService:onBind"); //创建 Messenger 对象(对 Handler 的引用) messenger = new Messenger(new IncomingHander(this)); //返回支持此Messenger的IBinder。 return messenger.getBinder(); } //实现了一个 Handler static class IncomingHander extends Handler { private Context appliacationContext; public IncomingHander(Context context) { appliacationContext = context.getApplicationContext(); } @Override public void handleMessage(Message msg) { switch (msg.what){ case MSG_SAY_HELLO: Bundle bundle = msg.getData(); String string = bundle.getString("name"); //处理来自客户端的消息 MLog.e("handleMessage:来自Acitvity的"+string); break; case 1: break; default: super.handleMessage(msg); } } } }
🌀 AndroidMainfest.xml
<service android:name=".ipc.MessengerService" android:process="com.scc.ipc.messengerservice" android:exported="true" android:enabled="true"/>
使用 android:process 属性 创建不同进程。
🌀 MainActivity.class
1.public class MainActivity extends ActivityBase implements View.OnClickListener { Messenger mService = null; Messenger messenger = null; private boolean bound; private ViewStub v_stud; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... } ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //从原始 IBinder 创建一个 Messenger,该 IBinder 之前已使用 getBinder 检索到。 mService = new Messenger(service); bound = true; } @Override public void onServiceDisconnected(ComponentName name) { bound = false; } }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_bind_service: bindService(new Intent(MainActivity.this, MessengerService.class), connection, Context.BIND_AUTO_CREATE); break; case R.id.btn_send_msg: Message message = Message.obtain(null, MessengerService.MSG_SAY_HELLO); Bundle bundle = new Bundle(); bundle.putString("name","Scc"); message.setData(bundle); try { mService.send(message); } catch (RemoteException e) { e.printStackTrace(); } break; } } @Override protected void onStop() { super.onStop(); if (bound) { unbindService(connection); bound = false; } } }
🌀 运行效果如下
两个进程也存在着,也完成了进程间的通信,并把数据传递过去了。
💥 实例(Server将数据传回Client)
我不仅想将消息传递给 Server ,还想让 Server 将数据处理后传会Client。
🌀 MessengerService.java
public class MessengerService extends Service { /** 用于显示和隐藏我们的通知。 */ ArrayList<Messenger> mClients = new ArrayList<Messenger>(); /** 保存客户端设置的最后一个值。 */ int mValue = 0; /** * 数组中添加 Messenger (来自客户端)。 * Message 的 replyTo 字段必须是应该发送回调的客户端的 Messenger。 */ public static final int MSG_REGISTER_CLIENT = 1; /** * 数组中删除 Messenger (来自客户端)。 * Message 的 replyTo 字段必须是之前用 MSG_REGISTER_CLIENT 给出的客户端的 Messenger。 */ public static final int MSG_UNREGISTER_CLIENT = 2; /** * 用于设置新值。 * 这可以发送到服务以提供新值,并将由服务发送给具有新值的任何注册客户端。 */ public static final int MSG_SET_VALUE = 3; //让客户端向IncomingHandler发送消息。 Messenger messenger = null; //当绑定到服务时,我们向我们的Messenger返回一个接口,用于向服务发送消息。 public IBinder onBind(Intent intent) { MLog.e("MessengerService-onBind"); //创建 Messenger 对象(对 Handler 的引用) messenger = new Messenger(new IncomingHander(this)); //返回支持此Messenger的IBinder。 return messenger.getBinder(); } //实现了一个 Handler class IncomingHander extends Handler { private Context appliacationContext; public IncomingHander(Context context) { appliacationContext = context.getApplicationContext(); } @Override public void handleMessage(Message msg) { switch (msg.what){ case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_SET_VALUE: mValue = msg.arg1; for (int i=mClients.size()-1; i>=0; i--) { try { mClients.get(i).send(Message.obtain(null, MSG_SET_VALUE, mValue, 0)); } catch (RemoteException e) { // 客户端没了。 从列表中删除它; //从后往前安全,从前往后遍历数组越界。 mClients.remove(i); } } default: super.handleMessage(msg); } } } }
🌀 MainActivity.java
public class MainActivity extends ActivityBase implements View.OnClickListener { Messenger mService = null; Messenger messenger = null; private boolean bound; private ViewStub v_stud; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... } ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //从原始 IBinder 创建一个 Messenger,该 IBinder 之前已使用 getBinder 检索到。 mService = new Messenger(service); bound = true; } @Override public void onServiceDisconnected(ComponentName name) { bound = false; } }; static class ReturnHander extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MessengerService.MSG_SET_VALUE: //我要起飞:此处处理 MLog.e("Received from service: " + msg.arg1); break; default: super.handleMessage(msg); } } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_bind_service: bindService(new Intent(MainActivity.this, MessengerService.class), connection, Context.BIND_AUTO_CREATE); break; case R.id.btn_send_msg: try { mMessenger = new Messenger(new ReturnHander()); Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; //先发一则消息添加Messenger:msg.replyTo = mMessenger; mService.send(msg); // Give it some value as an example. msg = Message.obtain(null, MessengerService.MSG_SET_VALUE, this.hashCode(), 0); //传入的arg1值:this.hashCode() mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } break; } } @Override protected void onStop() { super.onStop(); if (bound) { unbindService(connection); bound = false; } } }
🌀 运行效果如下
我们在MainActivity 的 Handler.sendMessger()中接收到了来自 MesengerService 的消息 。
本次 Messenger 进程间通信齐活,这只是个简单的Demo。最后咱们看一波源码。
🔥 Messenger 源码
💥 Messenger.java
public final class Messenger implements Parcelable { private final IMessenger mTarget; public Messenger(Handler target) { mTarget = target.getIMessenger(); } public void send(Message message) throws RemoteException { mTarget.send(message); } public IBinder getBinder() { return mTarget.asBinder(); } ... public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); } }
然后你会发现 只要代码还是在 IMessenger 里面,咱们去找找。
💥 IMessenger.aidl
package android.os; import android.os.Message; /** @hide */ oneway interface IMessenger { void send(in Message msg); }
💥 new Messenger(Handler handelr)
这里其实是用Handler 调用 getIMessenger() 。咱们去Handler.class里面转转。
@UnsupportedAppUsage final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; } } //创建了Messenger实现类 private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { msg.sendingUid = Binder.getCallingUid(); //Messenger调用send()方法,通过Handler发送消息。 //然后在服务端通过Handler的handleMessge(msg)接收这个消息。 Handler.this.sendMessage(msg); } }
💥 new Messenger(IBinder target)
package android.os; /** @hide */ public interface IMessenger extends android.os.IInterface { /** Default implementation for IMessenger. */ public static class Default implements android.os.IMessenger { @Override public void send(android.os.Message msg) throws android.os.RemoteException { } @Override public android.os.IBinder asBinder() { return null; } } /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.os.IMessenger { /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an android.os.IMessenger interface, * generating a proxy if needed. */ public static android.os.IMessenger asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); //判断是否在同一进程。 if (((iin!=null)&&(iin instanceof android.os.IMessenger))) { //同一进程 return ((android.os.IMessenger)iin); } //代理对象 return new android.os.IMessenger.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } ... } public void send(android.os.Message msg) throws android.os.RemoteException; }
看了上面代码你会发现这不就是个aidl吗? 什么是aidl,咱们下一篇继续讲到。