EventBus使用

简介

EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递,这里的事件可以理解为消息。EventBus 3.0中EventBus提供了EventBusAnnotationProcessor注解处理器来在编译期通过读取@Subscribe()注解并解析、处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息,这样就比在EventBus 2.x 采用反射的方式对整个注册的类的所有方法进行扫描来完成注册的速度要快

使用

首先添加引用 compile 'org.greenrobot:eventbus:3.0.0'

EventBus的主要元素
  • Event :事件,可以是任意类型的对象。
  • Publisher:事件发布者,用于通知Subscriber有事件发生
  • Subscriber :事件订阅者,接收特定的事件
  • ThreadMode :定义函数在何种线程中执行,主要包含四个ThreadMode
    1. ThreadMode.POSTING: 事件的处理在和事件的发送在相同的进程,所以事件处理时间不应太长,不然影响事件的发送线程,而这个线程可能是UI线程。
  1. ThreadMode.MAIN: 事件的处理会在UI线程中执行。事件处理时间不能太长,这个不用说的,长了会ANR的。
  2. ThreadMode.BACKGROUND: 事件的处理会在一个后台线程中执行,但事件处理时间还是不应该太长,因为如果发送事件的线程是后台线程,会直接执行事件,如果当前线程是UI线程,事件会被加到一个队列中,由一个线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。
  3. ThreadMode.AYSNC: 事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程(有线程池),但最好限制线程的数目。
使用的基本步骤
  1. 定义事件类型:
    public class Event {}
  2. 定义事件处理方法:
    public void onEvent
  3. 注册订阅者:
    EventBus.getDefault().register(this)
  4. 发送事件:
    EventBus.getDefault().post(new Event())
  5. 取消注册:
    EventBus.getDefault().unregister(this)
如下一个使用例子
  • 定义一个事件类型
public class Event {
    private String message;

    public Event(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
  • 处理事件
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册
        EventBus.getDefault().register(this);

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                Log.e("lwd", "hahha");
                startActivity(intent);
            }
        });
    }

    /**
     * 在这里处理事件
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 100)//在ui线程执行 优先级100
    public void onEvent(Event event) {
        String msg = event.getMessage();
        ((TextView) findViewById(R.id.tv)).setText(msg);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //反注册
        EventBus.getDefault().unregister(this);
    }
}

优先级越高优先获得消息,优先级高的订阅者可以终止事件往下传递 EventBus.getDefault().cancelEventDelivery(event) ;其中sticky=true表示黏性事件,为了方便理解成订阅在发布事件之后,但同样可以收到事件。发送粘性事件EventBus.getDefault().postSticky(new Event());如果不再需要该粘性事件我们可以移除EventBus.getDefault().removeStickyEvent(new DataSynEvent());,或者调用移除所有粘性事件EventBus.getDefault().removeAllStickyEvents();

  • 发送事件
public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        EventBus.getDefault().post(new Event("hahahaha"));
                    }
                }).start();
            }
        });
    }
}
调用不同的订阅函数

首先建立四个类:FirstEvent、SecondEvent、ThirdEvent 、FourthEvent。

public class FirstEvent {
    private String message;

    public FirstEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
public class SecondEvent{
    private String message;

    public SecondEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
public class ThirdEvent{
    private String message;

    public ThirdEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}
public class FourthEvent{
    private String message;

    public FourthEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

然后在MainActivity中,增加四种模式的订阅函数

/**
     * 在这里处理事件
     *
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN, priority = 100)
    public void onEventMain(FirstEvent event) {
        String msg = event.getMessage();
        Log.e("lwd", msg);
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND, priority = 100)
    public void onEventBackground(SecondEvent event) {
        String msg = event.getMessage();
        Log.e("lwd", msg);
    }

    @Subscribe(threadMode = ThreadMode.POSTING, priority = 100)
    public void onEventPosting(ThirdEvent event) {
        String msg = event.getMessage();
        Log.e("lwd", msg);
    }

    @Subscribe(threadMode = ThreadMode.ASYNC, priority = 100)
    public void onEventAsync(FourthEvent event) {
        String msg = event.getMessage();
        Log.e("lwd", msg);
    }

接下来在SecondActivity中增加四个按钮,分别发送不同类别的事件

findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new FirstEvent("我是1"));
            }
        }).start();
    }
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new SecondEvent("我是2"));
            }
        }).start();
    }
});
findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new ThirdEvent("我是3"));
            }
        }).start();
    }
});
findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new FourthEvent("我是4"));
            }
        }).start();
    }
});

分别顺序点击SecondActivity的四个按钮,打印信息如下:

10-18 11:18:47.723 10159-10159/com.example.luoweidong.eventbu E/lwd: 我是1
10-18 11:18:48.763 10159-10262/com.example.luoweidong.eventbu E/lwd: 我是2
10-18 11:18:49.863 10159-10281/com.example.luoweidong.eventbu E/lwd: 我是3
10-18 11:18:50.403 10159-10294/com.example.luoweidong.eventbu E/lwd: 我是4

由此可见,通过发布不同的事件类的实例,EventBus根据类的实例分别调用了不同的订阅函数来处理事件。订阅函数的执行是根据参数中的事件类的类名来决定的。

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

推荐阅读更多精彩内容

  • 前言:EventBus出来已经有一段时间了,github上面也有很多开源项目中使用了EventBus。所以抽空学习...
    Kerry202阅读 1,282评论 1 2
  • 本文的EventBus,是指greenrobot的 EventBus, 主要以EventBus3.0 讲解; 什么...
    Simon_z阅读 5,151评论 2 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 一、EventBus介绍 Android optimized event bus that simplifies ...
    獨家記憶丶阅读 937评论 0 49
  • 1.EventBus是一个基于观察者模式的事件发布/订阅框架,开发者通过极少的代码去实现多个模块之间的通信,而不需...
    newszhu阅读 414评论 0 0