EventBus 体验

之前一直都在用接口回调,或者是handler,感觉确实挺麻烦的,看到好多人都在用EventBus,并且之前自己也用过,但是不是很熟悉,所幸就记录下自己的使用心得。

1.前言:

在项目开发过程中,组件,线程的通信可谓用的非常之多,实现通信的方式大多就是使用Handler通信,或者是AsycTask实现UI的更新,亦或者可以通过接口的回调,来实现通信,另外还可以通过广播来更新信息。但是上述的几种通信方式大多都是代码量大,耦合度较高,使用起来比较繁琐。今天就来一起学习下EventBus.

2.简介:

EventBus是一种用于Android的发布/订阅事件总线,能够简化各组件间的通信,让我们的代码书写变得简单,能有效的分离事件发送方和接收方(也就是解耦的意思),能避免复杂和容易出错的依赖性和生命周期问题。

3.组成

EventBus由三部分组成:
(1) Event事件,也就是需要发送的消息
(2)Subscriber 事件订阅者.在3.0之后事件处理的方法名可以随意取,但是需要加上注解@subscribe(),并且指定线程模型
(3)Publisher 事件的发布者。我们可以在任意线程里发布事件,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post()方法即可。

4.线程模型

EventBus3.0有四种线程模型,分别是:

POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

5.基本使用

EventBus的使用非常简单,主要分为5个步骤:

定义事件。
注册事件。
订阅事件。
发布事件。
注销事件。

(1)定义一个事件,事件可以是任意普通的Java对象,没有任何特殊的要求

public class MessageEvent {
    private String message;

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

(2).注册事件,一般选择在Activity的onCreate()方法里去注册EventBus,在onDestory()方法里,去解除注册

@Override
protected void onCreate(Bundle savedInstanceState) {           
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     EventBus.getDefault().register(this);
}

(3)订阅事件,处理消息的方法名字可以随便取。但是需要加一个注解@Subscribe,并且要指定线程模型。

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

}

(4)发布事件,在需要的地方发布事件,所有订阅了该类型事件并已注册的订阅者将收到该事件

EventBus.getDefault().post(new MessageEvent("Hello EventBus!"));

(5)注销事件

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

6.完整Demo

第一步:添加依赖

compile 'org.greenrobot:eventbus:3.0.0'

第二步:定义消息事件类

public class MessageEvent{
    private String message;
    public  MessageEvent(String message){
        this.message=message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

第三步:注册和解除注册以及订阅事件

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";

    private TextView mTvMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initContentView();
        // 注册订阅者
        EventBus.getDefault().register(this);
    }

    private void initContentView() {
        Button btnStart = findViewById(R.id.btn_main_start_activity);
        mTvMessage = findViewById(R.id.tv_main_message);
        btnStart.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_main_start_activity) {
            SecondActivity.start(this);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        Log.i(TAG, "message is " + event.getMessage());
        // 更新界面
        mTvMessage.setText(event.getMessage());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销订阅者
        EventBus.getDefault().unregister(this);
    }
}

第四步:发布事件

public class SecondActivity extends AppCompatActivity implements View.OnClickListener {

    public static void start(Context context) {
        Intent intent = new Intent(context, SecondActivity.class);
        context.startActivity(intent);
    }

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

    private void initContentView() {
        findViewById(R.id.btn_second_post_event).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_second_post_event) {
            // 发布事件
            EventBus.getDefault().post(new MessageEvent("Hello EventBus!"));
        }
    }
}

7.粘性事件

如果先发布了事件,然后有订阅者订阅了该事件,那么除非再次发布该事件,否则订阅者将永远接收不到该事件。此时,可以使用粘性事件。发布一个粘性事件之后,EventBus将在内存中缓存该粘性事件。当有订阅者订阅了该粘性事件,订阅者将接收到该事件。注意:sticky = true,一定要写,默认是false .

订阅和发布一个粘性事件

// 订阅粘性事件
@Subscribe(sticky = true)
public void onMessageEvent(MessageEvent event) {
    ...
}

// 发布粘性事件
EventBus.getDefault().postSticky(new MessageEvent("Hello EventBus!"));

发布一个粘性事件之后,EventBus将一直缓存该粘性事件。如果想要移除粘性事件,那么可以使用如下方法:

// 移除指定的粘性事件
removeStickyEvent(Object event);

// 移除指定类型的粘性事件
removeStickyEvent(Class<T> eventType);

// 移除所有的粘性事件
removeAllStickyEvents();

Demo 如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

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

    private void initContentView() {
        findViewById(R.id.btn_main_post_event).setOnClickListener(this);
        findViewById(R.id.btn_main_start_activity).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_main_post_event:
                // 发布粘性事件
                EventBus.getDefault().postSticky(new MessageEvent("Hello EventBus!"));
                break;

            case R.id.btn_main_start_activity:
                SecondActivity.start(this);
                break;

            default:
                break;
        }
    }
}

当点击发布粘性事件的按钮时,MainActivity将发布一个MessageEvent粘性事件。

订阅粘性事件的代码如下所示:

public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";

    private TextView mTvMessage;

    public static void start(Context context) {
        Intent intent = new Intent(context, SecondActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        initContentView();
        // 注册订阅者
        EventBus.getDefault().register(this);
    }

    private void initContentView() {
        mTvMessage = findViewById(R.id.tv_second_message);
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onMessageEvent(MessageEvent event) {
        Log.i(TAG, "message is " + event.getMessage());
        // 更新界面
        mTvMessage.setText(event.getMessage());
        // 移除粘性事件
        EventBus.getDefault().removeStickyEvent(event);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销订阅者
        EventBus.getDefault().unregister(this);
    }
}

SecondActivity订阅了MessageEvent粘性事件。当接收到MessageEvent粘性事件时,订阅者方法将打印日志消息,并更新界面上的TextView,最后移除该粘性事件重点内容

总结

经过这个简单的例子,我们发现EventBus使用起来是如此的方便,当我们的代码量变得很多的时候,使用EventBus后你的逻辑非常的清晰,并且代码之间高度解耦,在进行组件、页面间通信的时候,EventBus是一个不错的选择。

参考:
https://blog.csdn.net/u012317510/article/details/78935720
https://www.jianshu.com/p/f9ae5691e1bb

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值