EventBus3.0开发详解 近万开发者收藏

来源:互联网 发布:傅红雪捏脸数据 编辑:程序博客网 时间:2024/06/06 00:25

什么是EventBus?

eventBus是GreenRobot公司出品的一个基于【publish/subscribe】模型的开发库

1、GreenRobot公司除了出品eventBus还出品了比较有名的greenDao(sqlite数据库的orm开发框架)

这里写图片描述

可以看出GreenDao的star数为4581 而EventBus的star数更高 9564 (star数是一个框架/项目影响力的指标)

2、publish/subscribe是一个以发送消息与接收消息模型。以前咱们学习过相似的知识点有

  • sendBroadcast与BroadcastReceiver是一个典型
  • handler.sendMessage与handleMessage(Message msg)也是一个典型
  • 所以该模型主要包含两个方面 一个是发送消息 一个是接收消息
    这里写图片描述

优点

  • 代码简洁、层次清晰,大大提高了代码的可读性和可维护性。
  • 可以通过简单的代码把数据传递给Activities, Fragments, Threads, Services等等

下载EventBus官方SDK

Github下载地址为:https://github.com/greenrobot/EventBus

EventBus3.0的使用

可以更简单的在 app/build.gradle中,如下配置即可
这里写图片描述

然后运行gradle脚本

这里写图片描述

EventBus的方法非常简洁只要掌握以下方法基本就可以完成企业开发了

1、注册与移除

方法 功能描述 EventBus.getDefault().register(this) 注册 EventBus.getDefault().unregister(this) 解除


以上两个方法使用上跟广播接收者的注册与使用是类似的有注册必须在使用后移除,以Activity为例:

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

2、发送消息

发布消息的对象即为【publisher】发布者

EventBus.getDefault().post(new MainMessage(“Hello EventBus”));

Post参数类型为普通javaBean

public class MainMessage {    private String msg;    public MainMessage(String msg) {        this.msg = msg;    }    public String getMsg() {        return msg;    }}

3、消息的接收处理(建议使用onEventXXX写法)

接收消息的对象即为【subscriber】 订阅者

//主线程中执行    @Subscribe(threadMode = ThreadMode.MainThread)    public void onMainEventBus(MainMessage msg) {        Log.d(TAG, "onEventBus() returned: " + Thread.currentThread());}

@Subscribe在案例中会细细地讲解 因为是一个大重点

4、案例分析:代替请求码与响应码

MainActivity请求一个NextPageActivity要求该NextPageActivity关闭时把数据传回给MainActivity

startActivityForResult请求代码略

在zaowu.itheima.com.eventbusdemo.demo1.FistEvent创建消息类(给post作为发送内容)

public class FistEvent {    private String msg;    public FistEvent(String msg) {        this.msg = msg;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }}

zaowu.itheima.com.eventbusdemo.demo1.MainActivity

加载布局:layout/activity_main.xml

这里写图片描述

注册与移除 订阅者

public class MainActivity extends AppCompatActivity {    private  TextView textView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        textView= (TextView) findViewById(R.id.main_activity_tv);        //注册事件        EventBus.getDefault().register(this);    }    @Override    protected void onDestroy() {        super.onDestroy();        //移除注册        EventBus.getDefault().unregister(this);    }    public void open(View view) {        startActivity(new Intent(this, NextPageActivity.class));    }

编写订阅者接收消息方法

@Subscribe(threadMode = ThreadMode.MAIN)public void onEventMainThread(FistEvent event) {    Log.i("itheima", "onEventMainThread:"+event.getMsg()+Thread.currentThread());    textView.setText(event.getMsg());}
  • @Subscribe设置订阅者接收处理消息的方法
  • 可以给该注解配置线程参数@Subscribe(threadMode = ThreadMode.MAIN)
  • ThreadMode用来指定线程

zaowu.itheima.com.eventbusdemo.demo1.NextPageActivity点击发送消息并关闭

public class NextPageActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_next_page);    }    public void event1(View view) {        //发送消息        FistEvent fistMessage = new FistEvent("NextPageActivity-FistEvent");        EventBus.getDefault().post(fistMessage);    }}

运行前后

这里写图片描述 –>这里写图片描述

控件制台显示:消息已经由NextPageActivity传给MainActivity了。显示main主线程

这里写图片描述
不过首先注意一点eventBus将消息传给参数类型一致的方法

eventBus底层post出消息后,会查找作为subscriber订阅者的参数类型一致的方法然后向这些方法传递post出来的消息。

所以当订阅者有两个以上参数类型一致的方法时都会接收到消息。

这里写图片描述

建议开发者创建不同的javaBean类来代表不同的消息类型

ThreadMode原理

这里写图片描述

方法 功能描述 ThreadMode.MAIN 标注方法运行在主线程,可以更新UI ThreadMode.BACKGROUND 标注方法运行在子线程,不可以更新UI但可以执行耗时代码 ThreadMode.POSTING 标注方法 运行在跟post一样的线程。如果post在主线程此时相当于MAIN,反之相当于BACKGROUND ThreadMode.ASYNC 标注方法运行在子程。但是跟BACKGROUND有区别。举个例子如果ASYNC标注的方法将要运行时有一个BACKGROUND标注的方法正在运行(延时10秒),前者标注的方法不会等待10秒结束再运行,而是另外开一个线程运行


以下是EventBus的源代码分析

这里写图片描述

案例分析:代替广播接收者

如果掌握了EventBus就可以不用广播接收者来发送消息接收消息了,用EventBus更简洁。

1、创建不同的消息对象

zaowu.itheima.com.eventbusdemo.demo2.MainEvent
zaowu.itheima.com.eventbusdemo.demo2.BackGroundEvent
zaowu.itheima.com.eventbusdemo.demo2.AsyncEvent
zaowu.itheima.com.eventbusdemo.demo2.PostingEvent

public class MainEvent {    private String msg;    public MainEvent(String msg) {        this.msg = msg;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }}

2、发送不同的消息

layout/activity_threadmode.xml
zaowu.itheima.com.eventbusdemo.demo2.ThreadModeActivity

这里写图片描述

public void event1(View view) {    //发送消息    MainEvent mainEvent = new MainEvent("MainEvent");    EventBus.getDefault().post(mainEvent);    Log.i("itheima", "post(mainEvent);"+System.currentTimeMillis());}public void event2(View view) {    //发送消息    BackGroundEvent backGroundEvent = new BackGroundEvent("BackGroundEvent");    EventBus.getDefault().post(backGroundEvent);    Log.i("itheima", "post(backGroundEvent);"+System.currentTimeMillis());}public void event3(View view) {    //发送消息    AsyncEvent asyncEvent = new AsyncEvent("AsyncEvent");    EventBus.getDefault().post(asyncEvent);    Log.i("itheima", "post(asyncEvent);"+System.currentTimeMillis());}public void event4(View view) {    //发送消息    PostingEvent postingEvent = new PostingEvent("PostingEvent");    EventBus.getDefault().post(postingEvent);    Log.i("itheima", "post(postingEvent);"+System.currentTimeMillis());}

3、接收消息

zaowu.itheima.com.eventbusdemo.demo2.ThreadModeActivity

@Subscribe(threadMode = ThreadMode.MAIN)public void onMainEvent(MainEvent event) {    Log.i("itheima", "onMainEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis());}@Subscribe(threadMode = ThreadMode.BACKGROUND)public void onBackGroundEvent(BackGroundEvent event) {    try {        Thread.sleep(10000);    } catch (InterruptedException e) {        e.printStackTrace();    }    Log.i("itheima", "onBackGroundEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis());}@Subscribe(threadMode = ThreadMode.ASYNC)public void onAsyncEvent(AsyncEvent event) {    Log.i("itheima", "AsyncEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis());}@Subscribe(threadMode = ThreadMode.POSTING)public void onPostingEvent(PostingEvent event) {    Log.i("itheima", "onPostingEvent接收事件:"+event.getMsg()+Thread.currentThread()+":"+System.currentTimeMillis());}

运行结果【按点击顺序】

这里写图片描述

【1】的运行结果为 ThreadMode.MAIN

这里写图片描述

【2】的运行结果为ThreadMode.BACKGROUND
消息发送到接收到经过了10秒 且运行在子线程

这里写图片描述

【3】的运行结果为ThreadMode.POSTING 与post在一个线程

这里写图片描述

【4】测试ThreadMode.ASYNC时按以下顺序

这里写图片描述

运行结果为

这里写图片描述
说明与ThreadMode.BACKGROUND都是子线程。但是如果后台有BACKGROUND在运行,ASYCN消息不会等待BACKGOUND完成,而是直接运行。

总结

有了EeventBus代码会更简洁。同时它比handler,广播,内容观察者的实现都简洁统一还支持消息接收的线程指定。开发者重点握:ThreadMode变量

原文出处:http://bbs.itheima.com/thread-299831-1-1.html

0 0
原创粉丝点击