轻量级进程间通信框架,基于 Messenger 实现。进程间传递数据不错的选择

网友投稿 1218 2022-10-17

轻量级进程间通信框架,基于 Messenger 实现。进程间传递数据不错的选择

轻量级进程间通信框架,基于 Messenger 实现。进程间传递数据不错的选择

概述

现在多进程传递数据使用越来越广泛了,在 Android 中进程间通信提供了 文件 、AIDL 、Binder 、Messenger 、ContentProvider 、Socket 、MemoryFile 等,实际开发中使用最多的应该是 AIDL ,但是 AIDL 需要编写 aidl 文件,如果使用 AIDL 仅仅是为了传递数据, 那么 YKProBus 是你不错的选择。

YKProBus

怎么使用?

1. root/build.gradle 中添加框架 maven

allprojects { repositories { ... maven { url 'https://jitpack.io' } } }

2. app/build.gradle 中添加框架 依赖

dependencies { implementation 'com.github.yangkun19921001:YKProBus:1.0.1' }

3. 发送进程绑定接收进程服务

EventManager.getInstance().bindApplication(Context context,String proName);

4. 发送消息

EventManager.getInstance().sendMessage(int messageTag,Bundle bundle);

5. 接收进程中需要在清单文件注册服务

6. 接收消息

6.1 在需要接收消息的类中实现 IMessageHandler 并实例化一个 Handler 用于接收发送进程发来的消息

public class MainActivity extends Activity implements IMessageHandler{ ... /** * 接收其它进程发送过来的消息 * * @return */ @Override public Handler getHandler() { return new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0x001: ... break; } } }; } ...}

6.2 注册当前类需要接收消息

EventManager.getInstance().registerMessager(int messageTag, Object obj);

框架设计大概流程

Messenger 源码分析

Messenger 内部其实也是依赖 aidl 实现的进程间通信。

服务端

@Override public IBinder onBind(Intent intent) { return mServiceMessenger.getServiceMessenger().getBinder(); }

getBinder() 跟进去

public IBinder getBinder() { return mTarget.asBinder(); }

mTarget 从何而来,从源码找找

public Messenger(Handler target) { mTarget = target.getIMessenger(); }

这里是我们实例化 服务端 Messenger 传入的 Handler target

/** * 初始化服务端 Messenger */ public MessengerManager() { if (null == mServiceMessenger) mServiceMessenger = new Messenger(mMessengerServiceHandler); }

final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; } }

private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { msg.sendingUid = Binder.getCallingUid(); Handler.this.sendMessage(msg); } }

这个是一个内部实现的类,可以看到继承的是 IMessenger.Stub 然后实现 send (Message msg) 函数,然后通过 mTarget.sendMessage(msg) 发送消息,最后在我们传入进去的 mMessengerServiceHandler 的 handleMessage (Message) 接收发来的消息。

既然这里内部帮我们写了 aidl 文件 ,并且也继承了 IMessenger.Stub 我们今天就要看到 aidl 才死心 , 好吧我们来找找 IMessenger aidl 文件。

内部就一个 send 函数,看到这,大家应该都明白了,Messenger 其实也没什么大不了,就是系统内部帮我们写了 aidl 并且也实现了 aidl ,最后又帮我们做了一个 Handler 线程间通信,所以服务端收到了客服端发来的消息。

客服端

客服端需要在 bindServicer onServiceConnected 回调中拿到 servicer, 平时我们自己写 应该是这么拿到 Ibinder 对象吧

IMessenger mServiceMessenger = IMessenger.Stub.asInterface(service);

但是我们实际客服端是这样拿到服务端的 Messenger

/** * 服务端消息是否连接成功 */ private class EventServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { isBindApplication = true; // 得到服务信使对象 mServiceMessenger = new Messenger(service); //将本地信使告诉服务端 registerMessenger(); String proName = ProcessUtils.getProName(mApplicationContext); Log.d(TAG, " EventServiceConnection " + proName); } @Override public void onServiceDisconnected(ComponentName name) { isBindApplication = false; } }

// 得到服务信使对象mServiceMessenger = new Messenger(service);

跟进去

public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target);}

这不就是我们刚刚说的自己实现的那种写法吧,到这里我们都懂了吧,我们平时写的 aidl android 中已经帮我们写了,想当于在 aidl 中封装下就变成了现在的 Messenger , 而我们又在 Messenger 上封装了下,想当于 三次封装了,为了使用更简单。封装才是王道!

总结

我们自己的 YKProBus 为了进程间通信使用更简单方便,其实相当于在 AIDL 中的三次封装。想要了解的可以去看下我具体的封装或者 Messenger 源码。

感谢大家抽空阅览文章,谢谢!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:02-Spring框架中Bean的生命周期
下一篇:MongoDB教程5-MongoDB的文档存储结构
相关文章

 发表评论

暂时没有评论,来抢沙发吧~