EventBus使用之基础

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

开源项目链接

EventBus项目:https://github.com/greenrobot/EventBus

EventBusDemo下载:https://github.com/yanbober/Android-Blog-Source/tree/master/Android-EventBus-Demo

背景介绍

如果你学习过设计模式,那么当想通知其他组件某些事情发生时你一定会使用观察者模式。好了,既然能想到这个设计模式,那么就来看一个屌爆天的Android开源框架EventBus。主要功能是替代Intent、Handler、BroadCast在Fragment、Activity、Service、线程之间传递消息。他的最牛逼优点是开销小,代码简洁,解耦代码。

基础介绍

上面说了,EventBus是一个观察者模式的实现,既然这样,那他就有如下三个要素:

  • Event:事件
  • Subscriber:事件订阅者,接收特定的事件。
  • Publisher:事件发布者,用于通知Subscriber有事件发生。

其中,Event可以使任意类型对象。Subscriber都是以约定的onEvent开头的函数,具体是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync这四个。Publisher可以通过post(Object)在任意线程任意位置发送事件。

依据开源库组件的说明文档来操作:

  1. 在工程gradle中添加:compile ‘de.greenrobot:eventbus:2.4.0’。
  2. 按照文档HOWTO.md进行操作。

Subscriber以onEvent开头的4个函数区别:

  • onEvent:事件的处理在和事件的发送在相同的线程,所以事件处理时间不应太长,不然影响事件的发送线程。
  • onEventMainThread: 事件的处理会在UI线程中执行。事件处理时间不能太长,长了会出现臭名远之的ANR。
  • onEventBackgroundThread:事件的处理会在一个后台线程中执行。虽然名字是BackgroundThread,事件处理是在后台线程,但事件处理时间还是不应该太长,因为如果发送事件的线程是后台线程,会直接在当前后台线程执行事件;如果当前线程是UI线程,事件会被加到一个队列中,由一个线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。
  • onEventAsync:事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程,但最好限制线程的数目。

下面还是先上代码再总结分析。

实战一把屌爆天的功能

如下示例演示了EventBus的线程间通信与线程内通信及自定义消息结构的通信。

下载该实例工程完整代码点击我

如下是主界面显示效果:

接着看代码:

首先自定义一个消息数据类型,如下:

public class MsgBean {
    private String msg;

    public MsgBean(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

接着编写主界面及逻辑代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView mShowInfo1, mShowInfo2, mShowInfo21, mShowInfo22;
    private Button mBtn1, mBtn2, mBtn21, mBtn22;

    private int mCount = 0;

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

        initData();
    }

    private void initData() {
        mShowInfo1 = (TextView) findViewById(R.id.first_show);
        mBtn1 = (Button) findViewById(R.id.get_btn_1);
        mBtn1.setOnClickListener(this);

        mShowInfo2 = (TextView) findViewById(R.id.second_show);
        mBtn2 = (Button) findViewById(R.id.get_btn_2);
        mBtn2.setOnClickListener(this);

        mShowInfo21 = (TextView) findViewById(R.id.first_show_lin2);
        mBtn21 = (Button) findViewById(R.id.get_btn_1_line2);
        mBtn21.setOnClickListener(this);

        mShowInfo22 = (TextView) findViewById(R.id.second_show_line2);
        mBtn22 = (Button) findViewById(R.id.get_btn_2_line2);
        mBtn22.setOnClickListener(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        //注册EventBus
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        //取消EventBus
        EventBus.getDefault().unregister(this);
    }

    //事件1接收者:在主线程接收
    public void onEvent(String event){
        mShowInfo1.setText(event);
    }
    //事件2接收者:在主线程接收自定义MsgBean消息
    public void onEvent(MsgBean event){
        mShowInfo21.setText(event.getMsg());
    }
    //事件3接收者:在主线程接收
    public void onEventMainThread(Integer event) {
        mShowInfo2.setText(event+"");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.get_btn_1:
                //事件1发送者:在主线程发送
                EventBus.getDefault().post("test!");
                break;
            case R.id.get_btn_1_line2:
                //事件2发送者:在主线程发送自定义MsgBean消息
                EventBus.getDefault().post(new MsgBean("type"));
                break;
            case R.id.get_btn_2:
                //事件3发送者:在子线程循环发送
                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        EventBus.getDefault().post(mCount);
                        if (mCount >= 3) {
                            this.cancel();
                            mCount = 0;
                        }
                        mCount++;
                    }
                }, 0, 1000);
                break;
        }
    }
}

xml代码太简单就省略了。

如下运行结果:

下载该实例工程完整代码点击我

从上面代码可以看见,当发过来一个消息的时候,EventBus区分onEventxxx被调运通过发送消息的参数类型区分(如:post(new MsgBean(“type”))对应onEvent(MsgBean event),post(“test!”)对应onEvent(String event))。

总结

通过上面基础实战发现,使用EventBus的基本步骤就是如下4步:

  1. 定义事件类型(或者不定义)。例如:MsgBean等
  2. 定义事件处理方法。例如:onEvent等
  3. 注册订阅者。例如:EventBus.getDefault().register(this)
  4. 发送事件。例如:EventBus.getDefault().post(new MyEvent())

通过这个例子基本上你就可以上手EventBus框架使用了,也知道了大致基本原理。其实这还是不够,玩意出现bug又很郁闷不知道怎么改,所以下一篇还是老规矩,走读一下EventBus的大致源码,学习下作者的代码思想,同时熟悉EventBus的原理。

时间: 2024-10-27 20:57:48

EventBus使用之基础的相关文章

94、EventBus框架 ---- 转载

EventBus使用之基础 http://blog.csdn.net/yanbober/article/details/45667363 EventBus框架库代码走读  http://blog.csdn.net/yanbober/article/details/45671407 EventBus源码解析 带你深入理解EventBus http://blog.csdn.net/lmj623565791/article/details/40920453 EventBus实战 http://blog

EventBus框架库代码走读

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 本篇继续接上一篇,阅读上一篇EventBus使用之基础 背景 开始分析EventBus前可以下看下EventBus开源框架的工程目录结构: 从上图可以发现,其实EventBus的代码量不是很大,还是很方便入手分析的. 开始分析 通过上一篇基础使用可以发现,使用EventBus框架第一步是得到

美团猫眼电影Android模块化实战总结

1 写这篇博客的初衷 首先一句话概括:我想把这几个月做的事情记录下来,并且希望尽量详细,希望读者读了这篇文章能够知道项目进行模块化,项目改业务框架可能会遇到哪些问题,具体每个步骤都做什么,而不是大致的了解. 现在很多人都在谈模块化,网上有一大堆的博客实践都在讲这个.很多谈的只是模块与模块之间的解耦,并且大部分讲的是通过router路由进行解耦,其他谈的不多,而且不乏泛泛而谈.但将一个app真正做到解耦,运行.需要解决的事情远远不止解耦.业务架构.进程间通信.资源等处理.解耦方式等都需要解决.恰好

java web 开发三剑客 -------电子书

Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知Internet的目的是让各个net交互.所以,Internet实质上是将世界上各个国家.各个网络运营商的多个网络相互连接构成的一个全球范围内的统一网,使各个网络之间能够相互到达.各个国家和运营商构建网络采用的底层技术和实现可能各不相同,但只要采用统一的上层协议(TCP/IP)就可以通过Internet

EventBus的使用和原理剖析

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38174537 代码下载:http://download.csdn.net/detail/yuanzeyao2008/7684041 在编程过程中,当我们想通知其他组件某些事情发生时,我们通常使用观察者模式,正式因为观察者模式非常常见,所以在jdk1.5中已经帮助我们实现了观察者模式,我们只需要简单的继承一些类就可以快速使用观察者模式,在Android中也有一个类似功能的开源库EventBu

EventBus使用详解(二)——EventBus使用进阶

一.概述 前一篇给大家装简单演示了EventBus的onEventMainThread()函数的接收,其实EventBus还有另外有个不同的函数,他们分别是: 1.onEvent2.onEventMainThread3.onEventBackgroundThread4.onEventAsync 这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事

android事件总线(eventbus)设计与实现

1. 功能介绍 AndroidEventBus是一个Android平台的事件总线库, 它简化了Activity.Fragment.Service等组件或者对象之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量. AndroidEventBus吸收了greenrobot的EventBus以及square的otto的优点,并在此基础上做出了相应的改进,使得事件总线框架更适合用户的使用习惯,也使得事件的投递更加的精准.灵活. 与EventBus.otto

EventBus 二

前一篇简单演示了EventBus的onEventMainThread()函数的接收,其实EventBus还有另外有个不同的函数,他们分别是: 1.onEvent2.onEventMainThread3.onEventBackgroundThread4.onEventAsync 这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下

Android事件驱动编程-基于EventBus(二)

Android事件驱动编程(二) --欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人同意请勿用于商业用途,谢谢-- 原文链接:https://medium.com/google-developer-experts/event-driven-programming-for-android-part-ii-b1e05698e440 本文Gitbooks链接:http://asce1885.gitbooks.io/android-rd-senior-adv