基于Agera的EventBus实现库

AgeraBus简介

AgeraBus 是基于谷歌开源的Agera实现的Android事件总线,实现了EventBus基本常用的功能,下面将为你一一介绍,如果要了解Agera,可以去看我文章后面推荐的两个地址。

添加依赖

在项目根目录的build.gradle中添加:

dependencies {
    compile 'xyz.zpayh:agerabus:1.0.4'
    compile 'com.google.android.agera:agera:1.3.0'
}

基本用法

一个事件总线的使用总是少不了订阅、取消、发送事件,还有获取数据,下面我们来看下AgeraBus的基本用法,首先我们定义一个普通的类充当一个事件类型:

public class User{

    private String mName;
    public User(String name){
        this.mName = name;
    }
    
    public void setName(String name){
        this.mName = name;
    }

    public String getName(){
        return this.mName;
    }
}

简单的订阅,注销事件以及获取最新数据:

public class BaseActivity extends Activity implements Updatable{

    ...

    @Override
    protected void onStart() {
        super.onStart();
        //register 同一个Updatable实例只能订阅同一种事件类型一次,如需重新
        //订阅,要先取消订阅,如果多次订阅会抛出异常,这里Activity实现了Updatable接口
        AgeraBus.getDefault()
                .addUpdatable(this,User.class);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // unregister 取消订阅时,这个Updatable实例必须已经订阅了此事件,
        // 如果取消没有订阅的Updatable,会抛出异常
        AgeraBus.getDefault()
                .removeUpdatable(this,User.class);
    }

    /**
     * 接收到事件时调用的接口
     * 
     */
    @Override
    public void update() {
        // accept
          AgeraBus.getDefault()//获取默认总线
                .getSupplier(User.class)//拿到数据提供者
                .get()//获取封装好的数据Result<User>
                .ifSucceededSendTo(new Receiver<User>() {//数据成功接收到就发送给接收者
                    @Override
                    public void accept(@NonNull User value) {
                        //打印吐司
                        Toast.makeText(BaseActivity.this, value.getName(), Toast.LENGTH_SHORT).show();
                    }
                });
    }
}

上面就是最基本的订阅、取消事件以及接收数据。至于发送事件的话,只有一个入口:

AgeraBus.getDefault().post(new User("Sherlock"));

上面就是AgeraBus最基本的用法,下面简单讲解一下,

Agera 使用 push event, pull data 模型(推送事件,拉取数据)。 push event:被观察者只做事件通知,不携带任何数据; pull data:观察者根据自己需要从数据仓库(Repository.get())拉取数据。

由于push event, pull data模型是数据和事件通知分离的,所以上面看到的Updatable接口设计上并没有携带数据过来的,我们在update方法里,如果要拉取数据,可以从AgeraBus拿到订阅事件的数据提供者:
Supplier,再从Supplier中获取数据。

进阶用法

EventBus 提供了线程分发,订阅优先级,取消事件分发,粘性事件,而这些在AgeraBus也都一一实现了。
使用这些高级功能时,我们的订阅方法是使用另外一个接口。下面会介绍到。

线程分发与线程模型

ThreadMode有四种:
PostThread,MainThread,BackgroundThread,Async.

  • PostThread 订阅者将会被调用在与发布线程同样的线程中。上面基本用法就是采取这样的线程分发的,不涉及线程切换,通常是四种模式开销最小的一个。对于简单任务来说这是推荐用法,但使用这个分发模型要小心不要在主线程执行耗时长的任务,避免阻塞主线程。
  • MainThread 订阅者将会被回调在Android的Main线程中,适用于更新UI而又不无法确定事件来源于哪个线程的情况。
  • BackgroundThread 订阅者将在后台线程被回调,如果发布线程本身不是主线程,那么行为就跟PostThread一致,如果是在主线程发布事件,会切换到后台线程执行。
  • Async 订阅者总是在一个单独的线程被回调。

订阅优先级

你可以在注册订阅者的时候设置优先级改变事件分发的顺序,按优先级从高到低分发事件回调。

取消事件分发

你可以在接收事件,拿到数据value之后中断之后的事件分发:

AgeraBus.getDefault().cancel(value);

value 是从Supplier拿到的事件的数据,在update中调用上面的取消分发,后续的订阅者将不会接收到此次事件。

粘性事件

Agera 的 push event, pull data模型天然就是支持粘性事件,它总会保存最近(最新)的值,这样订阅粘性事件总是可以拿到最近(如果有)的数据。

使用方法

要使用上面这些高级功能,我们用AgeraBus另外一个接口方法订阅事件:

    AgeraBus.getDefault()
                .compiler(User.class)//设置订阅事件的类型
                .priority(priority)//设置优先级,或者调用.noPriority()不设置优先级(即为默认0优先级)
                .sticky()//设置为接收粘性事件,或者调用.noSticky()设置为不接收粘性事件(默认不接收粘性事件)
                .background()//设置分发线程,有background(),main(),posting(),async()对应四个分发模式(默认为posting模式)
                .compile(updatable);//设置订阅者,完成订阅

订阅事件不要中断链式调用,最后一定要调用compile(Updatable)完成调用

基本用法中的:

    AgeraBus.getDefault()
                .addUpdatable(this,User.class);

就是全部设置了默认的方式(0优先级,不接收粘性事件,posting线程分发)。

注意

在不同线程分发时候拿到的数据,不一定是引发这次事件的数据,拿到的数据有可能要比引发事件的数据要新,在Agera Wiki 中文版中有说到,这是因为:

由于 push event, pull data 模型和多线程情况下,观察者可能看不到数据全部的更新记录。 这是特意设计的: 因为大多数情况下(尤其更新app UI), 本来就只需要关心最新的数据。

上面的使用方法可以参考我的这个项目地址 AgeraBus,里面有使用Demo。可以看下AgeraBus的具体实现,由于本人技术水平有限,如有Bug,欢迎讨论。

参考文章

zjutkz的要做一个有冒险精神的人!开启漫漫的agera之旅

Agera Wiki 中文版

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容