认识EventBus

来源:互联网 发布:淘宝旺铺有用吗 编辑:程序博客网 时间:2024/06/08 16:20

开源链接:https://github.com/greenrobot/EventBus

EventBus简介:

EventBus是一款针对Android优化的发布/订阅事件总线。
这里写图片描述

这幅图片表示的是:
发布者发布了(post)事件,EventBus通知订阅者,订阅者响应(onEvent)事件,做出改变。

这就是一个观察者模式。

优点

  • 简化应用程序内各组件间、组件与后台线程间的通信。
    • 解耦事件发布者和接受者
    • 在Activities,Fragment和后台线程中的执行更好
    • 避免一些复杂且易出错的依赖性和周期性问题。
  • 让代码更简单
  • 更快
  • 更小

简而言之:它可以让我们轻松的实现在Activity各个组件之间传递消息,代码的可读性会更好,耦合度更低。

EventBus的使用

1.添加依赖库,注意这是目前最新的版本,一起的版本和现在的使用会有所不同,事件处理时一定要使用@Subscribe注释,否则会报错

compile 'org.greenrobot:eventbus:3.0.0'

步骤

1.定义事件类

public static class MessageEvent { }

2.在需要订阅事件的地方注册事件

EventBus.getDefault().register(this);

3.发送事件

EventBus.getDefault().post(messageEvent);

4.处理事件,一定要加注释@Subscribe

@Subscribe(threadMode = ThreadMode.MAIN)public void XXX(MessageEvent messageEvent) {}

5.取消事件订阅

EventBus.getDefault().unregister(this);

简单的例子

这里写图片描述

流程为:
在MainActivity中点击Button跳转到SecondActivity中,在SecondActivity发布事件,由MainActivity接收并显示处理。(注意:SecondActivity中使用finish进行销毁)

创建事件:

//事件类public class MessageEvent  {    private  String message;    public MessageEvent(String message) {        this.message = message;    }    public String getMessage() {        return message;    }}

MainActivity的代码为:

  @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn_start = (Button) findViewById(R.id.btn_start);        textView = (TextView) findViewById(R.id.text);       //注册EventBus        EventBus.getDefault().register(this);        btn_start.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this, SecondActivity.class);                startActivity(intent);            }        });       @Override    protected void onDestroy() {        super.onDestroy();        //取消注册        EventBus.getDefault().unregister(this);    } //订阅者    @Subscribe(threadMode=ThreadMode.MAIN)    public void onEventMainThread(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", msg);        textView.setText(msg);    }

SecondActivity的代码为:

  @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        btn_post = (Button) findViewById(R.id.btn_post);        btn_post.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //发送事件                EventBus.getDefault().post(new MessageEvent("hello,this is SecondActivity"));                finish();//销毁掉SecondActivity,如果使用Intent跳转到MainActivity,在标准化模式下,会重新建立一个MainActivity,就不会显示收到的消息。            }        });        }

四种线程模型

  • POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
  • MAIN:事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
  • BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。
  • ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行。

黏性事件

这里写图片描述

黏性事件:发送事件之后,在订阅,也能够收到该事件。

上图演示的流程为:
点击Button跳转到SecondActivity,点击发布黏性事件Button,按返回键回到MainActivity。然后订阅事件,将内容显示出来。

我们将EventBus的注册事件放在了获取订阅事件的Button中

 //点击订阅按钮时才注册事件        btn_subscribe.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //判断EventBus是否已经注册,避免重复注册导致错误                if (!EventBus.getDefault().isRegistered(MainActivity.this)) {                    EventBus.getDefault().register(MainActivity.this);                }            }        });

在SecondActivity中发布黏性事件

  btn_sticky = (Button) findViewById(R.id.btn_sticky);        btn_sticky.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                EventBus.getDefault().postSticky(new MessageEvent("this is StickyEvent"+index++));//index记录点击次数                //finish();            }        });

MainActivity中接收事件:

 //订阅者    @Subscribe(threadMode=ThreadMode.MAIN,sticky = true)    public void onEventMainStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "MAIN->"+msg);        textView.setText(msg);    }

黏性事件接收最新事件

这里写图片描述

一共点击了6次,index从0计数,所以显示为5,表明黏性事件接收的事件为最新。
为了测试四种线程模式:

    //订阅者    @Subscribe(threadMode=ThreadMode.POSTING,sticky = true)    public void onEventPostStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "POST->"+msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.MAIN,sticky = true)    public void onEventMainStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "MAIN->"+msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.BACKGROUND,sticky = true)    public void onEventBackStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag","BACK->"+ msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.ASYNC,sticky = true)    public void onEventASYNCStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "ASYNC->"+msg);        textView.setText(msg);    }

这里写图片描述

设置sticky = false

   //订阅者    @Subscribe(threadMode=ThreadMode.POSTING,sticky = false)    public void onEventPostStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "POST->"+msg);        textView.setText(msg);    }

POSTING不显示:

这里写图片描述

以上就是我对EventBus的认识。

完整代码:

//MainActivitypublic class MainActivity extends AppCompatActivity {    private Button btn_start;    private TextView textView;    private Button btn_subscribe;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn_start = (Button) findViewById(R.id.btn_start);        textView = (TextView) findViewById(R.id.text);        btn_subscribe = (Button) findViewById(R.id.btn_subscribe);       /* //注册EventBus        EventBus.getDefault().register(this);*/        btn_start.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this, SecondActivity.class);                startActivity(intent);            }        });        //点击订阅按钮时才注册事件        btn_subscribe.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //判断EventBus是否已经注册,避免重复注册导致错误                if (!EventBus.getDefault().isRegistered(MainActivity.this)) {                    EventBus.getDefault().register(MainActivity.this);                }            }        });    }    //订阅者    @Subscribe(threadMode=ThreadMode.MAIN)    public void onEventMainThread(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.POSTING,sticky = false)    public void onEventPostStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "POST->"+msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.MAIN,sticky = true)    public void onEventMainStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "MAIN->"+msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.BACKGROUND,sticky = true)    public void onEventBackStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag","BACK->"+ msg);        textView.setText(msg);    }    //订阅者    @Subscribe(threadMode=ThreadMode.ASYNC,sticky = true)    public void onEventASYNCStick(MessageEvent event) {        String msg = "收到消息:" + event.getMessage();        Log.d("tag", "ASYNC->"+msg);        textView.setText(msg);    }    @Override    protected void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }}
//activity_main.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:orientation="vertical"    android:layout_height="match_parent"    tools:context="com.example.openresource.MainActivity">    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/btn_start"        android:text="start_Activity"        />    <TextView        android:id="@+id/text"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Hello World!"        android:gravity="center"        />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Subscribe"        android:id="@+id/btn_subscribe"        /></LinearLayout>
//SecondActivitypublic class SecondActivity extends Activity {    private Button btn_post;    private Button btn_sticky;    private int index;//计算点击次数    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        btn_post = (Button) findViewById(R.id.btn_post);        btn_post.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //发送事件                EventBus.getDefault().post(new MessageEvent("hello,this is SecondActivity"));                finish();//销毁掉SecondActivity,如果使用Intent跳转到MainActivity,在标准化模式下,会重新建立一个MainActivity,就不会显示收到的消息。            }        });        btn_sticky = (Button) findViewById(R.id.btn_sticky);        btn_sticky.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                EventBus.getDefault().postSticky(new MessageEvent("this is StickyEvent"+index++));                //finish();            }        });    }}
//activity_second.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >    <TextView        android:gravity="center"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Second Activity"        />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/btn_post"        android:text="send_msg"        />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="send_sticky"        android:id="@+id/btn_sticky"        /></LinearLayout>

参考:
http://www.jianshu.com/p/da9e193e8b03#
http://blog.csdn.net/itachi85/article/details/52205464

原创粉丝点击