Otto是一个在Android中的事件总线框架,它是square的一个开源框架,具体介绍点击这里,项目下载点击这里

为什么要使用Otto事件总线:

通常来说在Android中:

1、Activity与Activity间的传值是通过Intent,值回调是通过startActivityForResult()

2、Activity与Fragment间的传值是通过setArguments,值回调是通过实现onAttach()的Interface方式

3、而Fragment与Fragment间的交互则应该是通过它们关联的Activity作为中间键来交互

4、包括Activity与Service的交互,可能众多同学会采用Binder机制来处理,而其实Binder机制本质也是通过接口回调方式来进行值回调的

5、或者在更复杂的应用场景下,比如:ActivityA跳转到ActivityB,ActivityB跳转到ActivityC,此时需要从ActivityC中获取到用户的操作数据返回到ActivityA和ActivityB中显示,或者在Activity中有多个Fragment,其中一个Fragment里的数据变化需要同步更新其它Fragment的数据变化,这时候如果使用Interface的方式进行它们间的交互则比较复杂,耦合度也高

所以,针对上面这些问题,大多数在处理值交互的问题上类之间都是耦合在一起的,而Otto事件总线框架就是降低各个类间的耦合度的。

Otto事件总线

Otto中真正用到的就只有一个类两个注解三个方法:

  1. Bus - 管理注册、注销和发布事件
  2. @Produce - 标记该方法是生产者,产生的事件内容为该方法的返回值
  3. @Subscribe - 标记该方法是订阅者,表示订阅了一个事件,方法需要修饰符为public,而区分不同的订阅者是通过方法的参数来区分的,且订阅了某事件的所有订阅者都可以收到该事件
  4. register(Object obj) - 注册,订阅事件前都需要注册
  5. unregister(Object obj) - 注销,放弃之前所有事件的订阅
  6. post(Object event) - 发布一个事件,这个事件会被所有标记了@Subscribe注解的方法获得

使用Otto事件总线

首先添加依赖:

dependencies {
    compile 'com.squareup:otto:+'
}

1、为了避免重复创建Bus对象,我们先为Bus创建一个单例对象

public class BusProvider {
    private volatile static Bus bus = null;

    private BusProvider() {
    }

    public static Bus getInstance() {
        if (bus == null) {
            synchronized (BusProvider.class) {
                bus = new Bus();
            }
        }
        return bus;
    }
}

2、创建一个Bean,用来传递各类间的数据

public class EventData {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

3、在MainActivity中注册并且创建订阅者订阅数据

public class MainActivity extends AppCompatActivity {

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

        BusProvider.getInstance().register(this);//订阅事件

        Button mButton = (Button) findViewById(R.id.btn);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TestActivity.jumpToTestActivity(MainActivity.this);
            }
        });
    }
    @Subscribe
    public void subscribeEvent(EventData data){
        Log.v("zxy", data.getContent());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        BusProvider.getInstance().unregister(this);//注销订阅
    }

    public static void jumpToMainActivity(Context context){
        context.startActivity(new Intent(context,MainActivity.class));
    }
}

4、在TestActivity中发布事件

发布事件有两种方法:

1、使用@Produce注解来生产事件,不过它生产事件前它需要注册、生产完事件后需要注销,如果使用这种方法则在跳转到生产者所在的类中则会立即产生事件触发订阅者,即在MainActivity跳转到TestActivity时,会立即产生事件并订阅了该事件的方法会收到该事件,如:

public class TestActivity extends AppCompatActivity {

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

        BusProvider.getInstance().register(this);
    }

    @Produce
    public EventData produceEvent(){
        EventData mEventData = new EventData();
        mEventData.setContent("hello word!");
        return mEventData;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        BusProvider.getInstance().unregister(this);
    }

    public static void jumpToTestActivity(Context context){
        context.startActivity(new Intent(context, TestActivity.class));
    }
}

则在MainActivity跳转到TestActivity时订阅者会马上收到事件,输出的Log信息为:

09-06 03:46:16.738    5958-5958/? V/zxy﹕ hello word!

2、通过post()来发布事件,它不需要注册和注销,而且它不会在界面跳转时马上发布事件,而是我们人为的控制该事件什么时候发布,使用如下:

public class TestActivity extends AppCompatActivity {

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

    public void click(View view){
        EventData mEventData = new EventData();
        mEventData.setContent("hello word!");
        BusProvider.getInstance().post(mEventData);//发布事件

        MainActivity.jumpToMainActivity(this);
    }

    public static void jumpToTestActivity(Context context){
        context.startActivity(new Intent(context, TestActivity.class));
    }
}

当我们点击按钮时候,这个事件就发布出去了,而订阅了该事件的方法就会收到,打印的Log为:

09-06 03:46:18.738    5958-5958/? V/zxy﹕ hello word!

【注】:发布事件需要发布的是一个Object对象,而且这个对象不能为null,所以在数据量大的时候我们可以创建个Bean类,而传当个数据时候如字符串等则直接传String就好。

可以看到通过Otto事件总线来处理类与类之间的交互,可以使得我们的代码更容易理解,类与类之间也解耦了

Otto事件总线框架的使用的更多相关文章

  1. Android学习系列(43)--使用事件总线框架EventBus和Otto

    事件总线框架 针对事件提供统一订阅,发布以达到组件间通信的解决方案. 原理 观察者模式. EventBus和Otto 先看EventBus的官方定义: Android optimized event ...

  2. 事件总线框架---Otto

    我们假设这样一种业务场景,现在在做一款及时聊天应用,我们在聊天页面进行收发信息,同时也要实时更新前一页面的聊天记录,这时我们该如何去实现?说说我以前的实现策略,我使用的是广播接收器BroadCastR ...

  3. android开源项目之OTTO事件总线(二)官方demo解说

    官方demo见  https://github.com/square/otto 注意自己该编译版本为2.3以上,默认的1.6不支持match_parent属性,导致布局文件出错. 另外需要手动添加an ...

  4. android开源项目之OTTO事件总线(一)

    Otto是由Square发布的一个着重于Android支持的基于Guava的强大的事件总线,在对应用程序不同部分进行解耦之后,仍然允许它们进行有效的沟通. 开源项目地址:https://github. ...

  5. EventBus事件总线框架(发布者/订阅者模式,观察者模式)

    一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...

  6. Android--Otto事件总线 -- 组件之间通讯框架使用 --模式解析

    前言:Otto事件总线 -- 组件之间通讯框架 对于之前的情况activity之间或者fragment之间等跳转传值一般都是用bundle.intent等,从activityA --- activit ...

  7. 事件总线帧---Otto

    我们如果这样一种业务场景.如今在做一款及时聊天应用,我们在聊天页面进行收发信息.同一时候也要实时更新前一页面的聊天记录,这时我们该怎样去实现?说说我曾经的实现策略.我使用的是广播接收器BroadCas ...

  8. AndroidEventBus ( 事件总线 ) 的设计与实现

    1. 功能介绍 AndroidEventBus是一个Android平台的事件总线库, 它简化了Activity.Fragment.Service等组件或者对象之间的交互,非常大程度上减少了它们之间的耦 ...

  9. Android事件总线EventBus详解

    顾名思义,AndroidEventBus是一个Android平台的事件总线框架,它简化了Activity.Fragment.Service等组件之间的交互,很大程度上降低了它们之间的耦合,使我们的代码 ...

随机推荐

  1. Android TV开发总结(六)构建一个TV app的直播节目实例

    请尊重分享成果,转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52966319 近年来,Android TV的迅速发展,传统的有线电视受 ...

  2. Unity UGUI实现分段式血条

    我们可以看到像英雄联盟等游戏里英雄头顶的血条显示并非是纯色的,而是根据血量的多少而显示一定量的格子,这种方式明显是比较友好.比较美观的,事实上我们的游戏里面也想实现这样的效果,那该怎么办呢?根据血量的 ...

  3. 自定义progressDialog(数据加载框)的实现

    大家在开发客户端时基本上都需要获取数据,在获取数据时会有一个等待状态,这时我们可以利用系统自带的progressDialog来向用户展示"数据正在加载中..."等等,但有时我们会觉 ...

  4. 28 自定义View画坐标和柱状图

    自定义View类 RectView.java package com.qf.sxy.day29_customview.widget; import android.content.Context; i ...

  5. Redis工作系列之一 与 Memcached对比理解

         近期公司项目在使用Redis,这几年Redis很火,Redis也常常被当作Memcached的挑战者被提到桌面上来.关于Redis与Memcached的比较更是比比皆是.然而,Redis真的 ...

  6. RxJava操作符(06-错误处理)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51658235 本文出自:[openXu的博客] 目录: Catch Retry 源码下载 1 ...

  7. Cocos2D与SpriteBuilder的问题在哪提问

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道Cocos2D的教程中文版的非常少,注意我没有说Coc ...

  8. mysql进阶(二十六)MySQL 索引类型(初学者必看)

    mysql进阶(二十六)MySQL 索引类型(初学者必看)   索引是快速搜索的关键.MySQL 索引的建立对于 MySQL 的高效运行是很重要的.下面介绍几种常见的 MySQL 索引类型.   在数 ...

  9. Java学习之栈和堆的区别

    在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配 ...

  10. Android动态加载入坑指南

    曾几何时,国内各大公司掀起了一股研究Android动态加载的技术,两年多过去了,动态加载技术俨然成了Android开发中必须掌握的技术.那么动态加载技术是什么呢,这里谈谈我的个人看法,如有雷同,纯属偶 ...