[转载]EventBus 3.0 入门使用

转载链接

https://www.jianshu.com/p/acfe78296bb5

前言

EventBus是greenrobot在Android平台发布的一款以订阅—发布模式为核心的开源库。EventBus翻译过来是事件总线的意思,可以这样理解:一个个事件(event)发送到总线上,然后EventBus根据已注册的订阅者(subscribers)来匹配相应的事件,进而把事件传递给订阅者,这也是观察者模式的一个最佳实践。
那么EventBus可以用到什么地方呢?事件传递既可用于 Android 四大组件间通讯,也可以用户异步线程和主线程间通讯等等。而使用EventBus能极大简化两个组件之间的通信问题,而且效率极高,而EventBus升级到3.0版本后,开发者能够自定义订阅方法的名字,而且支持了粘性事件的分发等,因此学会使用EventBus3.0对我们的开发有极大的好处。

传统的事件传递方式包括:Handler、BroadCastReceiver、Interface 回调,相比之下 EventBus 的优点是代码简洁,使用简单,并将事件发布和订阅充分解耦。

使用

依赖

在Android Studio中添加如下依赖:

compile 'org.greenrobot:eventbus:3.0.0'

创建事件实体类

所谓的事件实体类,就是传递的事件,一个组件向另一个组件发送的信息可以储存在一个类中,该类就是一个事件,会被EventBus发送给订阅者。


public class MessageEvent {

    private String message;

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

    public String getMessage(){
        return message;
    }
}

注册

即可将当前类注册,成为订阅者,即对应观察者模式的“观察者”,一旦有事件发送过来,该观察者就会接收到匹配的事件。通常,在类的初始化时便进行注册,如果是Activity则在onCreate()方法内进行注册。

EventBus.getDefault().register(this);

解除注册

当订阅者不再需要接受事件的时候,我们需要解除注册,释放内存:

EventBus.getDefault().unregister(this);

声明订阅方法

在EventBus 3.0中,声明一个订阅方法需要用到@Subscribe注解,因此在订阅者类中添加一个有着@Subscribe注解的方法即可,方法名字可自定义,而且必须是public权限,其方法参数有且只能有一个,另外类型必须为第一步定义好的事件类,如下所示:

@Subscribe 
public void onEvent(AnyEventType event) {
    /* Do something */
}
public class MainActivity extends Activity {

    private TextView textView;
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注册成为订阅者
        EventBus.getDefault().register(this);
        textView = (TextView) findViewById(R.id.tv_text);
        button = (Button) findViewById(R.id.secondActivityBtn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }
    
    //订阅方法,当接收到事件的时候,会调用该方法
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MessageEvent messageEvent){
        Log.d("cylog","receive it");
        textView.setText(messageEvent.getMessage());
        Toast.makeText(MainActivity.this, messageEvent.getMessage(), Toast.LENGTH_SHORT).show();
    }


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

发送事件

与观察者模式对应的,当有事件发生,需要通知观察者的时候,被观察者会调用notifyObservers()方法来通知所有已经注册的观察者,在EventBus中,对观察者模式底层进行了封装,我们只需要调用以下代码就能把事件发送出去:

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_main);
        Button button = (Button) findViewById(R.id.sendMessageBtn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new MessageEvent("Hello !....."));
            }
        });
    }
}

由此可见,经过以上简单的四个步骤,就能实现事件在组件之间的传递了,这是EventBus的便捷性。

进一步认识@Subscribe注解

我们回头看看上面的订阅方法,添加了@Subscribe注解,该注解标识了当前方法为订阅方法,我们可以看到上面我们还给该注解赋值(threadMode = ThreadMode.MAIN),那么,这个代表了什么意思呢?首先,我们看看@Subscribe的类文件:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean sticky() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
}

该注解内部有三个成员,分别是threadMode、sticky、priority。threadMode代表订阅方法所运行的线程,sticky代表是否是粘性事件,priority代表优先级。给这个三个成员赋不同的值,能使得订阅方法有着不同的效果。

ThreadMode是一个枚举类型,有着以下几个类型:

public enum ThreadMode {
    //发送线程(默认)
    POSTING,
    //主线程
    MAIN,
    //后台线程
    BACKGROUND,
	//后台线程
    ASYNC
}

POSTING:表示订阅方法运行在发送事件的线程。
MAIN:表示订阅方法运行在UI线程,由于UI线程不能阻塞,因此当使用MAIN的时候,订阅方法不应该耗时过长。
BACKGROUND:表示订阅方法运行在后台线程,如果发送的事件线程不是UI线程,那么就使用该线程;如果发送事件的线程是UI线程,那么新建一个后台线程来调用订阅方法。
ASYNC:订阅方法与发送事件始终不在同一个线程,即订阅方法始终会使用新的线程来运行。
ThreadMode默认是使用POSTING的,如果需要更改设置,可以在添加注解的时候同时为threadMode赋值。

priority 优先级

设置该优先级的目的是,当一个事件有多个订阅者的时候,优先级高的会优先接收到事件。值越小优先级越低,默认为0。

sticky 粘性事件

关于粘性事件,可以参考Android的广播机制,其中有一个粘性广播,粘性广播的意思是:该广播发送后,会保存在内存中,如果后来有注册的Receiver与之匹配,那么该Receiver便会接收到该广播。那么粘性事件同理,在注册之前便把事件发生出去,等到注册之后便会收到最近发送的粘性事件(必须匹配)。注意:只会接收到最近发送的一次粘性事件,之前的会接受不到。
为了测试,我们来建立一个小demo:
我们在Activity中添加四个按钮,布局很简单不给出了,前三个按钮分别发送三个粘性事件,最后一个按钮进行注册,代码如下:

public class SecondActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_main);
        Button button1 = (Button) findViewById(R.id.sendStickyMessageBtn1);
        Button button2 = (Button) findViewById(R.id.sendStickyMessageBtn2);
        Button button3 = (Button) findViewById(R.id.sendStickyMessageBtn3);
        Button button4 = (Button) findViewById(R.id.sendRegisterBtn);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.sendStickyMessageBtn1:
                EventBus.getDefault().postSticky(new MessageEvent("粘性事件1"));
                Log.d("cylog","发送粘性事件1...");
                break;
            case R.id.sendStickyMessageBtn2:
                EventBus.getDefault().postSticky(new MessageEvent("粘性事件2"));
                Log.d("cylog", "发送粘性事件2...");
                break;
            case R.id.sendStickyMessageBtn3:
                EventBus.getDefault().postSticky(new MessageEvent("粘性事件3"));
                Log.d("cylog", "发送粘性事件3...");
                break;
            case R.id.sendRegisterBtn:
                Log.d("cylog", "注册成为订阅者...");
                EventBus.getDefault().register(this);

                break;
        }
    }

    @Subscribe(sticky = true)
    public void onEvent(MessageEvent messageEvent){
        Log.d("cylog","接受到了来自EventBus的事件:"+messageEvent.getMessage());
    }

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

我们依次按下这4个按钮,按先后次序发送粘性事件1、2、3以及注册订阅者,我们可以看到下面的结果:只会接受到最后发送的粘性事件,在此之前的事件都接收不到。

建议

推荐大家在使用EventBus的时候,创建一个事件类,把你的每一个参数(或者可能发生冲突的参数),封装成一个类:

public class Event  {  
    public static class UserListEvent {  
        public List<User> users ;  
    }
    public static class ItemListEvent {  
        public List<Item> items;  
    }    
}  

添加processor

按照Markus Junginger的说法(EventBus创作者),在3.0中,如果你想进一步提升你的app的性能,你需要添加:

provided 'de.greenrobot:eventbus-annotation-processor:3.0.0-beta1'

其在编译的时候为注册类构建了一个索引,而不是在运行时,这样的结果是其让EventBus 3.0的性能提升了一倍,相比2.4来说,其会是它的3到6倍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EventBus是一种用于Android应用程序中发布/订阅事件的库。它遵循发布-订阅模式,允许不同组件之间进行松散耦合的通信。 在基于EventBus 3.0的APP开发中,你可以按照以下步骤进行: 1. 添加EventBus依赖 在项目的build.gradle文件中添加以下代码: ``` dependencies { implementation 'org.greenrobot:eventbus:3.2.0' } ``` 2. 创建事件类 创建一个事件类,它将包含你需要发送和接收的数据。例如: ``` public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = message; } } ``` 3. 注册订阅者 在需要接收事件的组件中,注册订阅者。例如,在Activity中: ``` @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } ``` 4. 发布事件 在需要发送事件的组件中,发布事件。例如,在Activity中: ``` EventBus.getDefault().post(new MessageEvent("Hello, world!")); ``` 5. 处理事件 在订阅者中,创建一个方法来处理接收到的事件。例如,在Activity中: ``` @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) { // Do something with the event Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show(); } ``` 以上就是基于EventBus 3.0的APP开发的基本步骤。通过使用EventBus,你可以轻松地在不同组件之间传递数据,从而实现应用程序中的松散耦合通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值