Android事件总线 ( AndroidEventBus ) 框架发布

AndroidEventBus

AndroidEventBus是一个Android平台的事件总线框架, 它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。

在往下看之前,你可以考虑这么一个场景,两个Fragment之间的通信你会怎么实现?

按照Android官方给的建议的解决方法如下: Communicating with the Activity,思路就是Activity实现某个接口,然后在Fragment-A关联上Activity之后将Activity强转为接口类型,然后在某个时刻Fragment中回调这个接口,然后再从Activity中调用Fragment-B中方法。这个过程是不是有点复杂呢? 如果你也这么觉得,那也就是你继续看下去的理由了。

基本结构

AndroidEventBus类似于观察者模式,通过register函数将需要订阅事件的对象注册到事件总线中,然后根据@Subcriber注解来查找对象中的订阅方法,并且将这些订阅方法和订阅对象存储在map中。当用户在某个地方发布一个事件时,事件总线根据事件的参数类型和tag找到对应的订阅者对象,最后执行订阅者对象中的方法。这些订阅方法会执行在用户指定的线程模型中,比如mode=ThreadMode.ASYNC则表示该订阅方法执行在子线程中,更多细节请看下面的说明。

与greenrobot的EventBus的不同

  1. greenrobot的EventBus是一个非常流行的开源库,但是它在使用体验上并不友好,例如它的订阅函数必须以onEvent开头,并且如果需要指定该函数运行的线程则又要根据规则将函数名加上执行线程的模式名,这么说很难理解,比如我要将某个事件的接收函数执行在主线程,那么函数名必须为onEventMainThread。那如果我一个订阅者中有两个参数名相同,且都执行在主线程的接收函数呢? 这个时候似乎它就没法处理了。而且规定死了函数命名,那就不能很好的体现该函数的功能,也就是函数的自文档性。AndroidEventBus使用注解来标识接收函数,这样函数名不受限制,比如我可以把接收函数名写成updateUserInfo(Person info),这样就灵活得多了。
  2. 另一个不同就是AndroidEventBus增加了一个额外的tag来标识每个接收函数可接收的事件的tag,这类似于Broadcast中的action,比如每个Broadcast对应一个或者多个action,当你发广播时你得指定这个广播的action,然后对应的广播接收器才能收到.greenrobot的EventBus只是根据函数参数类型来标识这个函数是否可以接收某个事件,这样导致只要是参数类型相同,任何的事件它都可以接收到,这样的投递原则就很局限了。比如我有两个事件,一个添加用户的事件, 一个删除用户的事件,他们的参数类型都为User,那么greenrobot的EventBus大概是这样的:

private void onEventMainThread(User aUser) {
    // code
}

如果你有两个同参数类型的接收函数,并且都要执行在主线程,那如何命名呢 ? 即使你有两个符合要求的函数吧,那么我实际上是添加用户的事件,但是由于EventBus只根据事件参数类型来判断接收函数,因此会导致两个函数都会被执行。AndroidEventBus的策略是为每个事件添加一个tag,参数类型和tag共同标识一个事件的唯一性,这样就确保了事件的精确投递。

这就是AndroidEventBus和greenrobot的EventBus的不同,但是由于本人对greenrobot的EventBus并不是很了解,很可能上述我所说的有误,如果是那样,欢迎您指出。

AndroidEventBus起初只是为了学习,但是在学习了EventBus的实现之后,发现它在使用上有些不便之处,我想既然我有这些感觉,应该也是有同感之人,在开发群里交流之后,发现确实有这样的情况。因此才将正式地AndroidEventBus以开源库的形式推出来,希望能够帮助到一些需要的人。当然,这个库的成长需要大家的支持与测试,欢迎大家发 pull request。如果你需要的是一个相对稳定的库,greenrobot的EventBus和square的otto都是非常好的选择。

使用AndroidEventBus

你可以按照下面几个步骤来使用AndroidEventBus.

  • 1 注册事件接收对象

public class YourActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        // 注册对象
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDestroy() {
        // 不要忘记注销!!!!
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}
  • 2 通过Subscriber注解来标识事件接收对象中的接收方法
public class YourActivity extends Activity {
    // code ......

    // 接收方法,默认的tag,执行在UI线程
    @Subcriber
    private void updateTime(String time) {
        Log.e("", "### update time = " + time);
    }

    // 含有my_tag,当用户post事件时,只有指定了"my_tag"的事件才会触发该函数,执行在UI线程
    @Subcriber(tag = "my_tag")
    private void updateTimeWithTag(String time) {
        Log.e("", "### update time with my_tag, time = " + time);
    }

    // 含有my_tag,当用户post事件时,只有指定了"my_tag"的事件才会触发该函数,
    // post函数在哪个线程执行,该函数就执行在哪个线程
    @Subcriber(tag = "my_tag", mode=ThreadMode.POST)
    private void updateTimeWithMode(String time) {
        Log.e("", "### update time with my_tag, time = " + time);
    }

    // 含有my_tag,当用户post事件时,只有指定了"my_tag"的事件才会触发该函数,执行在一个独立的线程
    @Subcriber(tag = "my_tag", mode = ThreadMode.ASYNC)
    private void updateTimeAsync(String time) {
        Log.e("", "### update time async , time = " + time + ", thread name = " + Thread.currentThread().getName());
    }
}

接收函数使用tag来标识可接收的事件类型,与BroadcastReceiver中指定action是一样的,这样可以精准的投递消息。mode可以指定目标函数执行在哪个线程,默认会执行在UI线程,方便用户更新UI。目标方法执行耗时操作时,可以设置mode为ASYNC,使之执行在子线程中。

  • 3 在其他组件,例如Activity, Fragment,Service中发布事件
    EventBus.getDefault().post("what‘s the time now ?");

    // post a event with tag, the tag is like broadcast‘s action
    EventBus.getDefault().post(new Date().toLocaleString(), "my_tag");

发布事件之后,注册了该事件类型的对象就会接收到响应的事件.

Github链接

欢迎star和fork, AndroidEventBus框架

时间: 2025-01-12 08:48:04

Android事件总线 ( AndroidEventBus ) 框架发布的相关文章

【第三篇】学习 android 事件总线androidEventbus之发布事件,子线程中接收

发送和接收消息的方式类似其他的发送和接收消息的事件总线一样,不同的点或者应该注意的地方: 1,比如在子线程构造方法里面进行实现总线的注册操作: 2,要想子线程中接收消息的功能执行,必须启动线程. 3,添加tag和不添加tag类似其他. 1 package com.example.mysimpleeventbus; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.simple.eventbus.Even

【第一篇】学习 android 事件总线androidEventbus之sticky事件的传递

最近再看eventbus相关代码,首先从使用开始,后期再从源码角度分析eventbus.使用Demo后期公布到github上去. 使用的框架地址:https://github.com/bboyfeiyu/AndroidEventBus Sticky 事件 使用例子: 1,首先每个Activity或者fragement都要进行eventBus的注册和反注册. 发送sticky事件的activity: 1 package com.example.mysimpleeventbus; 2 import

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

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

Android事件总线

Android事件总线还能怎么玩? 顾名思义,AndroidEventBus ( github链接 ,关于我为什么要写这个库请参考<AndroidEventBus ( 事件总线 ) 的设计与实现>)是一个Android平台的事件总线框架,它简化了Activity.Fragment.Service等组件之间的交互,很大程度上降低了它们之间的耦合,使我们的代码更加简洁,耦合性更低,提升了我们的代码质量.但它能做的却不仅限于这些.经过定制,它能完成很多有意思的功能,那么究竟该怎么做呢?就让我们一起往

Android退出程序(三)——Android事件总线

概述 当我们跟随时间的脚步向前挪动的时候,总能发现原来以前的自己做了一些愚蠢的事情.但,不见得以前就是不好的事情.我在以前的博客中写过两种关于Android中如何退出应用程序的方法.近日,我又发现了一个看似高大上的方法,因为作为程序员的你,使用起来会更加方便.它就像是你得心应手的工具,在需要的时候让你有一种,还好有它的感觉.下面我就使用Android事件总线来对Android退出程序作一个说明. AndroidEventBus简介 AndroidEventBus是一个Android平台的事件总线

Android 事件总线OTTO使用说明和源码解析

一.Otto简单介绍 OTTO是Square推出的库,地址:https://github.com/square/otto 先来看看otto的官方介绍 An enhanced Guava-based event bus with emphasis on Android support.Otto is an event bus designed to decouple different parts of your application while still allowing them to c

Android事件总线分发库EventBus3.0的简单讲解与实践

Android事件总线分发库EventBus的简单讲解与实践 导语,EventBus大家应该不陌生,EventBus是一款针对Android优化的发布/订阅事件总线.主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅.以及将发送者和接收者解耦.反正能帮助我们快速开发,这个确实是个好东西,其实鸿洋大神已经对源码作了一个较全面的剖析了 Android EventBus源码解析 带你深入理解Ev

Android事件总线(二)EventBus3.0源码解析

相关文章 Android事件总线(一)EventBus3.0用法全解析 前言 上一篇我们讲到了EventBus3.0的用法,这一篇我们来讲一下EventBus3.0的源码以及它的利与弊. 1.构造函数 当我们要调用EventBus的功能时,比如注册或者发送事件,总会调用EventBus.getDefault()来获取EventBus实例: public static EventBus getDefault() { if (defaultInstance == null) { synchroniz

android事件总线(eventbus)开源库发布

 AndroidEventBus 如果你不知道事件总线是什么,那么没有关系,下面我们先来看这么一个场景: 你是否在开发的过程中遇到过想在Activity-B中回调Activity-A中的某个函数,但Activity又不能手动创建对象来设置一个Listener什么的? 你是否想在某个Service中想更新Activity或者Fragment中的界面? 等等之类的组件之间的交互问题-- 一经思考,你会发现Android中的Activity, Fragment, Service之间的交互是比较麻烦的,