Android 开源框架 ( 七 ) 事件总线---EventBus

  

一.引言

         与四大组件之一的BroadCast广播比较,广播主要监听系统级事件,比如网络切换,电池电量等属于进程间的通信,EventBus 是进程内的通信。
         了解BroadCast 可以查看该文章:Android 四大组件 (三) BroadcastReceiver 介绍

二.基本使用

  引入类库:

compile ‘com.jakewharton:butterknife:8.5.1‘

  页面打开时候初始化并注册EventBus

//初始化

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

  页面销毁时候解除EventBus注册

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

  发布事件 publish

//发布事件
 EventBus.getDefault().post(new EventBean("我来自第二个页面的触发"));

  接受者 subscribe.注意方法名可以随便取,但是参数类型与publish发布者的保持一致. 这里是EventBean

//订阅者事件,处理事件反馈的消息
 @Subscribe
 public void OnEvent(EventBean bean) {
  //拿到发布者传过来的event事件带的消息
  String msgStr = bean.getMsg();
  //UI打印出拿到的消息
  tvFirst.setText(msgStr);
 }

三.ThreadMode 分析

  五种 ThreadMode介绍 

    ThreadMode.MAIN 订阅者将在Android的主线程(有时称为UI线程)中被调用。如果发布线程是主线程,则将直接调用事件处理程序方法(与ThreadMode.POSTING中描述的同步)。使用此模式的事件处理程序必须快速返回以避免阻塞主线程.
    ThreadMode.MAIN_ORDERED 订阅者将在Android的主线程中被调用。该事件总是排队等待以后传递给订阅者。这给事件处理一个更严格和更一致的顺序(因此名字MAIN_ORDERED)。例如,如果使用MAIN线程模式在事件处理程序中发布另一个事件,
则第二个事件处理程序将在第一个事件处理程序之前完成(因为它被同步调用 - 将其与方法调用进行比较)。使用MAIN_ORDERED,第一个事件处理程序将完成,然后第二个将在稍后的时间点被调用(只要主线程有能力).
    ThreadMode.BACKGROUND 订阅者将在后台线程中被调用。如果发布线程不是主线程,则会在发布线程中直接调用事件处理程序方法。如果发布线程是主线程,则EventBus将使用一个后台线程来按顺序发送所有事件。使用这种模式的事件处理程序应该尽快返回以避免阻塞后台线程。
    ThreadMode.ASYNC 事件处理程序方法在单独的线程中调用。这总是独立于发布线程和主线程。发布事件永远不会等待使用此模式的事件处理程序方法。事件处理程序方法应该使用这种模式,如果它们的执行可能需要一些时间,
例如网络访问。避免同时触发大量长时间运行的异步处理程序方法来限制并发线程的数量。EventBus使用线程池有效地重用已完成异步事件处理程序通知中的线程。
    ThreadMode.POSTING这是默认的。订阅者将在发布该事件的同一个线程中被调用。事件传递是同步完成的,所有订阅者一旦发布完成就被调用。这个ThreadMode意味着最小的开销,因为它避免了完全的线程切换。
因此,对于已知完成的简单任务而言,这是推荐的模式,其时间很短,不需要主线程。使用这种模式的事件处理程序应该快速返回以避免阻塞发布线程,这可能是主线程。

  源码查看下五种ThreadMode不同处理方式:

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch (subscription.subscriberMethod.threadMode) {
         //发送和订阅者在同一线程内
            case POSTING:
                invokeSubscriber(subscription, event);
                break;
       //主线程
            case MAIN:
                if (isMainThread) {
                    invokeSubscriber(subscription, event);
                } else {
                    mainThreadPoster.enqueue(subscription, event);
                }
                break;
         //
            case MAIN_ORDERED:
                if (mainThreadPoster != null) {
                    mainThreadPoster.enqueue(subscription, event);
                } else {
                    // temporary: technically not correct as poster not decoupled from subscriber
                    invokeSubscriber(subscription, event);
                }
                break;
       //后台,不能并发处理
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
         //子线程 异步并发处理
            case ASYNC:
                asyncPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }
    }

四.粘性事件

  简单说就是: 发送事件之后再订阅该事件也能收到该事件。同样Android 中也有同样的粘性事件机制,如 粘性广播(Sticky Broadcast).

  粘性事件使用场景:

  一些事件进行信息感兴趣的事件后发布。 例如,一个事件信号,一些初始化完成。 或者如果你有传感器位置数据和你想抓住最近的值。 而不是实现自己的缓存,您可以使用黏性的事件。 EventBus保持过去的事件的特定类型在内存中。 黏性的事件可以交付给用户或显式查询。 因此,你不需要任何特殊的逻辑来考虑可用的数据。

  粘性使用示例:

// 1创建一个粘性事件类
 public class StickyEvent {
  public String msg;
  public StickyEvent(String msg) {
   this.msg = msg;
  }
 }
 // 2 发送粘性事件
 EventBus.getDefault().postSticky(new StickyEvent("我是粘性事件"));
  // 3 接收粘性事件
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void StickyEventBus(StickyEvent event){
        // 显示接收的数据
        tv_eventbus_send_result.setText(event.msg);
    }
// 4.接收粘性事件数据按钮的点击事件处理
 bt_eventbus_send_sticky.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
     //true第一次点击,防止重复注册
       if(isFirstFlag) {
          isFirstFlag = false;
          // 4 注册
          EventBus.getDefault().register(EventBusSendActivity.this);
       }
    }
 });
@Override
    protected void onDestroy() {
        super.onDestroy();
        // 5 解注册
        EventBus.getDefault().removeAllStickyEvents();
        EventBus.getDefault().unregister(EventBusSendActivity.this);
    }

原文地址:https://www.cnblogs.com/bugzone/p/eventbus.html

时间: 2024-12-14 03:36:13

Android 开源框架 ( 七 ) 事件总线---EventBus的相关文章

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

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

android 开源框架推荐

同事整理的 android 开源框架,个个都堪称经典.32 个赞! 1.volley 项目地址 https://github.com/smanikandan14/Volley-demo (1)  JSON,图像等的异步下载: (2)  网络请求的排序(scheduling) (3)  网络请求的优先级处理 (4)  缓存 (5)  多级别取消请求 (6)  和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 2.android-async-http  项目地址:ht

六款值得推荐的Android开源框架简介

技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的“性价比”比较高的Android开源框架,应该是相对实用的. 1.volley 项目地址 https://github.com/smanikandan14/Volley-demo JSON,图像等的异步下载: 网络请求的排序(scheduling) 网络请求的优先级处理 缓存 多级别取消请求 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 2.android-async-http 项目地址:https:

自己动手写事件总线(EventBus)

本文由云+社区发表 事件总线核心逻辑的实现. EventBus的作用 Android中存在各种通信场景,如Activity之间的跳转,Activity与Fragment以及其他组件之间的交互,以及在某个耗时操作(如请求网络)之后的callback回调等,互相之之间往往需要持有对方的引用,每个场景的写法也有差异,导致耦合性较高且不便维护.以Activity和Fragment的通信为例,官方做法是实现一个接口,然后持有对方的引用,再强行转成接口类型,导致耦合度偏高.再以Activity的返回为例,一

.Net Core 基于CAP框架的事件总线

.Net Core 基于CAP框架的事件总线 CAP 是一个在分布式系统中(SOA,MicroService)实现事件总线及最终一致性(分布式事务)的一个开源的 C# 库,她具有轻量级,高性能,易使用等特点. github:https://github.com/dotnetcore/CAP doc:http://cap.dotnetcore.xyz CAP是一款优秀的框架,但是CAP在消息订阅的处理类必须使用[CapSubscribe]特性来绑定,本人觉得不是很科学. 好在2.5.1版本开放了接

Android开源框架Afinal第一篇——揭开圣女的面纱

Android开源框架Afinal第一篇——揭开圣女的面纱 分类: Android开源框架哪点事2013-09-02 14:25 260人阅读 评论(0) 收藏 举报 Afinal 这是Afinal在github的地址:https://github.com/yangfuhai/afinal Afinal这个框架主要分4块: 1.FinalDB模块:android中的orm框架,一行代码就可以进行增删改查.支持一对多,多对一等查询. 2.FinalActivity模块:android中的ioc框架

事件总线EventBus使用详解

EventBus源码解析 概述 EventBus是针一款对Android的发布/订阅事件总线.它可以让我们很轻松的实现在Android各个组件之间传递消息,并且代码的可读性更好,耦合度更低. 如何使用 (1)首先需要定义一个消息类,该类可以不继承任何基类也不需要实现任何接口.如: 123 public class MessageEvent { ......} (2)在需要订阅事件的地方注册事件 1 EventBus.getDefault().register(this); (3)产生事件,即发送

【DDD-Apwork框架】事件总线和事件聚合器

第一步:事件总线和事件聚合器 [1]事件总线 IEventBus IUnitOfWork.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Keasy5.Infrastructure { /// <summary> /// 表示所有集成于该接口的类型都是Unit Of Work的一种实现.

Android 开源框架 ( 五 ) xUtils --- Android 里的 ORM IOC聚合型框架

xUtils同Afinal一样属于聚合型框架, 大而全,但是越容易牵一发而动全身.所以不推荐使用,只做了解即可.应付手头临时项目. Android 开源框架 ( 四 ) Afinal --- Android 里的 ORM IOC聚合型框架 一.Xutils 介绍 Xutils是基于afinal开发的,但是比afinal稳定性提高了不少.xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事