Android消息传递之基于RxJava实现一个EventBus - RxBus(四)

前言:

上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事件总线管理,现在很多人都在说用这种方式来替代EventBus,今天我们从开发效率,开发难度等维度来分析一下到底能不能取代EventBus? 先回顾一下什么是EventBus?请看这篇文章Android消息传递之EventBus 3.0使用详解(三)

需求:

虽然软件工程师就害怕听见“需求”这两个字,但是一切功能来源于需求,我们要基于RxJava实现一个publish/subscribe消息总线管理模型,这里假设你已经知道如何使用RxJava了。下面看看如何实现。

RxBus实现过程:

1.)build.gradle中添加RxJava、RxAndroid引用

  compile ‘io.reactivex:rxandroid:1.1.0‘
  compile ‘io.reactivex:rxjava:1.1.2‘

2.)声明一个管理事件总线的单例

public class RxBus {
    private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>();
    private static volatile RxBus instance;

    private RxBus() {
    }

    public static RxBus getInstance() {
        RxBus inst = instance;
        if (inst == null) {
            synchronized (RxBus.class) {
                inst = instance;
                if (inst == null) {
                    inst = new RxBus();
                    instance = inst;
                }
            }
        }
        return inst;
    }
}

考虑到RxBus单例很有可能多线程并发访问,这种存储事件总线采用ConcurrentHashMap

3.)订阅者实现注册/解除注册方法

注册/解注册都以一个tag为唯一标示,这里采用的是事件的Class为tag,来实现一个Event事件对象可以对应多个订阅者。

  /**
     * 注册
     *
     * @param tag
     * @return
     */
    public <T> Observable<T> register(@NonNull Class<T> tag) {
        List<Subject> subjectList = subjectMapper.get(tag);
        if (null == subjectList) {
            subjectList = new ArrayList<>();
            subjectMapper.put(tag, subjectList);
        }
        Subject<T, T> subject = PublishSubject.create();
        subjectList.add(subject);
        return subject;
    }

    /**
     * 解除注册
     *
     * @param tag
     */
    public <T> void unregister(@NonNull Class<T> tag, @NonNull Observable observable) {
        List<Subject> subjects = subjectMapper.get(tag);
        if (null != subjects) {
            subjects.remove(observable);
            if (subjects.isEmpty()) {
                subjectMapper.remove(tag);
            }
        }
    }

4.)实现发送消息、清除所有注册

发送一个事件消息是通过获取当前事件下的订阅者列表,然后通过一个循环进行事件传递。至于事件运行在哪个线程中由订阅者决定。

 /**
     * 发送消息
     *
     * @param event
     */
    public <T> void post(@NonNull Object event) {
        List<Subject> subjectList = subjectMapper.get(event.getClass());
        if (subjectList != null && !subjectList.isEmpty()) {
            for (Subject subject : subjectList) {
                subject.onNext(event);
            }
        }
    }

    /**
     * 清除订阅
     */
    public void clear() {
        if (subjectMapper.isEmpty()) {
            return;
        }
        subjectMapper.clear();
    }

5.)如何使用

事件的订阅者的注册和清除所有注册,订阅者没订阅一个类型的事件都要返回一个Observable对象,这也是个人觉得比较头疼的一件事,很难实现一个订阅者对应多个事件类型,而且解注册的时候也需要这些Observable对象进行一一解除。

    private Observable<DataSynEvent> observable;
    private void registerObservable() {
        observable = RxBus.getInstance().register(DataSynEvent.class);
        observable.observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<DataSynEvent>() {
            @Override
            public void call(DataSynEvent event) {
                Log.e(TAG, "event--2-->" + event.getCount());
            }
        });
    }

    private void unRegisterObservable() {
        if (observable != null) {
            RxBus.getInstance().unregister(DataSynEvent.class, observable);
        }
    }

事件的发送者发送事件,发送事件的处理还算比较友好,和EventBus很类似。

  RxBus.getInstance().post(new DataSynEvent());

RxBus、EventBus 对比:

1.从引入依赖包对比

RxBus 需要引入两个包,EventBus需要引入一个,如果项目中没有使用到RxJava编程的话,并不能减少包的依赖。

2 .从开发难度上对比

上面也提到了实现RxBus是基于RxJava的,作为一个新的编程方式函数式编程,对开发者的要求多多少少提高了那么一点,而且每一个订阅都需要返回一个Observable,由订阅者写具体的代码 需要执行在哪个线程中,而EventBus 最新版本采用注解预编译的方式,订阅者注册解注册只需调用一个函数,而且通过注解的方式可以标明事件的优先级,接收事件运行在哪个线程,并且能够实现粘性事件,这些RxBus都需要进行二次开发。

3.)从开发效率上对比

RxBus 需要进行大量的二次开发,否则只能实现简单的事件传递,而EventBus只需简单了解一下API就能上手。如果一个订阅者需要注册多个事件的时候,需要多个Observable全局变量,这不是疯掉了吗,而EventBus已经实现了一个订阅者订阅多个事件,和一个事件对应多个订阅者。

4.)从功能完善上对比

    上面三个对比也说明了,EventBus实现了事件的优先级,订阅事件运行的线程场景,以及粘性事件,这些在RxBus上面都需要进行二次实现。

总结:

基于RxJava实现简单的事件总线管理是可以的,但是个人觉得想要取代EventBus难免有点说过头了。所以如果项目中没有使用RxJava的话 还是采用EventBus比较靠谱。

时间: 2024-08-25 16:24:25

Android消息传递之基于RxJava实现一个EventBus - RxBus(四)的相关文章

[android架构篇]mvp+rxjava+retrofit+eventBus

android架构篇 mvp+rxjava+retrofit+eventBus 高层不应该知道低层的细节,应该是面向抽象的编程.业务的实现交给实现的接口的类.高层只负责调用. 首先,要介绍一下一个项目中好架构的好处:好的软件设计必须能够帮助开发者发展和扩充解决方案,保持代码清晰健壮,并且可扩展,易于维护,而不必每件事都重写代码.面对软件存在的问题,必须遵守SOLID原则(面向对象五大原则),不要过度工程化,尽可能降低框架中模块的依赖性. 之前的一段时间,学习了一些新的技术,并把自己关注的技术整合

Android-MVP+Retrofit+Rxjava实现一个知乎日报客户端

使用MVP+Retrofit+Rxjava实现一个知乎日报客户端,界面基于Material design,还没有全部完成orz,,放假太懒 效果图 开源项目 name introduction butterknife Annotate fields with @BindView and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout. MaterialT

【Android开发经验】用RxJava.Observable取代AsyncTask和AsyncTaskLoader-RxJava Android模版

转载请注明出处http://blog.csdn.net/zhaokaiqiang1992 欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件架构设计.测试等文章 译者 : ZhaoKaiQiang 校对者: chaossss 状态 : 校对完成 在网上有很多关于RxJava入门指南的帖子,其中一些是基于Android环境的.但是,我想到目前为止,很多人只是沉迷于他们所看到的这些,当要解决在他们的Android项目中出现的具体问题时,他们并

给 Android 开发人员的 RxJava 具体解释

鉴于 RxJava 眼下这样的既火爆又神奇的现状,而我又在一年的使用过程中对 RxJava 有了一些理解,我决定写下这篇文章来对 RxJava 做一个相对具体的.针对 Android 开发人员的介绍. 这篇文章的目的有两个: 1. 给对 RxJava 感兴趣的人一些入门的指引 2. 给正在使用 RxJava 但仍然心存疑惑的人一些更深入的解析. 在正文開始之前的最后,放上?GitHub?链接和引入依赖的?gradle?代码: Github:? https://github.com/Reactiv

Android 如何编写基于编译时注解的项目

本文已在CSDN<程序员>杂志刊登. 本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发. 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/51931859: 本文出自:[张鸿洋的博客] 一.概述 在Android应用开发中,我们常常为了提升开发效率会选择使用一些基于注解的框架,但是由于反射造成一定运行效率的损耗,所以我们会更青睐于编译时注解的框架,例如: butterknife免去我们编写

Android系统中基于Binder的IPC流程框架分析

前言: Activity.Service.BroadcastReceiver.Content Provider是Android的四大应用程序组件,构成一个完整的应用程序的这些组件可以在同一个进程,也可以不在同一个进程,而当这些组件不在同一个进程,需要进行数据交互时就需要一种IPC(Inter-Process Communication)进程间通信机制来完成,而Binder就是提供了IPC功能的一个框架.实现IPC的整个Binder框架包含几个重要组成部分,它们分别是Binder Driver.C

Android消息传递机制

背景需求 在Android中,当遇到子线程需要刷新UI时,最常的做法就是handler,当然还有其他方便的方法如Android给我们提供的runOnUiThread(runnable)方法,但归根结底都是使用handler来刷新UI的. Android消息传递原理 简单的讲:handler发送(post或send)一条消息:MessageQueue(队,实际上是一个用单链表实现的队列)接受并存储该消息:looper无限循环的从MessageQueue中取出一条消息,例如msg,然后调用msg.t

看eShopOnContainers学一个EventBus

最近在看微软eShopOnContainers 项目,看到事件总线觉得不错,和大家分享一下 看完此文你将获得什么? eShop中是如何设计事件总线的 实现一个InMemory事件总线eShop中是没有InMemory实现的,这算是一个小小小的挑战 发布订阅模式 发布订阅模式可以让应用程序组件之间解耦,这是我们使用这种模式最重要的理由之一,如果你完全不知道这个东西,建议你先通过搜索引擎了解一下这种模式,网上的资料很多这里就不再赘述了. eShop中的EventBus就是基于这种模式的发布/订阅.

基于php的一个最简单的memcache的分布式算法

首先,核心函数是这个 function mHash($key){ $md=substr(md5($key),0,8); $seed=31; $hash=0; for($i=0;$i<8;$i++){ $hash=$hash*$seed+ord($md5{$i}); } return $hash & 0x7FFFFFFF; } class HashServer{ private $serverlist; private $issorted=false; function addServer($