EventBus使用过程中,遇到的问题点

说到EventBus,想必大家都不陌生,咦~~~~你没听过,好吧,你还要认真学习啊,这篇博客不是去分析EventBus的源码的,也不是讲什么人生哲理,就是教大家如何使用这么一个神器,以后谁要是问你Eventbus会不会用。。。你就可以骄傲的炫耀你的车技了,并将他领上车

1.初步理解

好了先上一张图体会一下这个的好处,是不是省了很多事,感觉又要复制粘贴一段话,放在下面,每次复制粘贴都反觉到深深的罪恶感。。。 
这里写图片描述
  EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。 
  顺便粘个源码的地址,我知道你是不会去看的,这是EventBus在GitHub上的开源库地址:https://github.com/greenrobot/EventBus

2.新手入门入门

好了下面直接教大家如何使用 
(1)EventBus配置 
EventBus框架也是采用建造者模式设计的,可以通过EventBusBuilder来设置一些配置信息,例如设置debug模式下要抛出异常

EventBus     eventBus=EventBus.builder().throwSubscriberException(BuildConfig.DEBUG.build();

 
 
  • 1
  • 2
  • 1
  • 2
(2)添加引用
compile 'org.greenrobot:eventbus:3.0.0'
 
 
  • 1
  • 1
( 3 ) 定义一个事件类型
public class MyEvent {
    private String msg;//所要发送的信息内容,你也可以写点别的啥
    public MyEvent(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
(4)订阅/解除订阅
EventBus.getDefault().register(this);//订阅

EventBus.getDefault().unregister(this);//解除订阅
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

有人问我这玩意儿放在哪里,好吧,我告诉你放在哪里,首先写一个封装类,

public class EventUtil {
//注册事件
    public static void register(Object context) {
        if (!EventBus.getDefault().isRegistered(context)) {
            EventBus.getDefault().register(context);
        }
    }
    //解除
    public static void unregister(Object context) {
        if (EventBus.getDefault().isRegistered(context)) {
            EventBus.getDefault().unregister(context);
        }
    }
    //发送消息
    public static void post(Object object) {
        EventBus.getDefault().post(object);
    }

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

然后如果是Activity内接收消息,就在onCreate和onDestroy中调用,如果是fragment呢,好吧也是还是在这两个方法中。。。。。。。不过就变成了

 EventUtil.register(this);//订阅事件
 EventUtil.register(this);//取消事件
 
 
  • 1
  • 2
  • 1
  • 2

(5)发布事件

EventBus.getDefault().post(new DataSynEvent());
 
 
  • 1
  • 1
(6)订阅事件处理
    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onDataSynEvent(DataSynEvent event) {

    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

ThreadMode总共四个:

NAIN UI主线程 
BACKGROUND 后台线程 
POSTING 和发布者处在同一个线程 
ASYNC 异步线程

他们有啥子用呢,其实就是告诉你只有在主线程中才能更新UI,主线程中不要做耗时操作,如果有必要需要和handler一起使用

(7)订阅事件的优先级

说到优先级,其实和Boardcast接收者的优先级差不多,数越大优先级越高,一般0-100吧

 @Subscribe(threadMode = ThreadMode.MAIN,priority = 100) //在ui线程执行 优先级100
    public void onDataSynEvent(DataSynEvent event) {

    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

有了优先级,有人就该问了,是不是可以对消息进行截获,不让它往下发呢,这个当然可以了

  EventBus.getDefault().cancelEventDelivery(event) ;//优先级高的订阅者可以终止事件往下传递
 
 
  • 1
  • 1
(8)EventBus黏性事件
我们在学广播的时候有一种广播叫粘性广播。如果使用普通广播send一个消息,然后在你的onReceive中执行超过10秒的话,这个广播的状态就会变为可以被干掉的状态,而粘性广播就是为了解除这个10秒限制。但是为了安全起见,忘了在哪个版本的SDK把这玩意给废弃掉了。

那么回到我们的问题,当你发送消息的时刻注册消息接收的时刻 并不能确定顺序,比如你请求网络数据订阅事件 同时执行,如果数据返回的特别快呀快,那你 EventUtil.register(this)这句代码还没执行完呀,这时候你就就收不到这个消息了

这个概念这么理解,就像qq邮件里有个订阅的功能,如果你订阅了一个公众邮件, 
那么他们就会给你推送消息,但是你却接收不到你订阅之前他们推送的消息

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //在ui线程执行
    public void onDataSynEvent(DataSynEvent event) {

    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.4版本的时候有一个发送粘性事件的方法, 后来发现原来3.0还是有这个方法的,所以就这么发送粘性事件

EventBus.getDefault().postSticky(new TestEvent());
 
 
  • 1
  • 1

我们知道这个粘性事件是存在静态变量里的,就是如果你不干掉他,他就一直在,这时候需要在的onDestory中调用这个

EventBus.getDefault().removeStickyEvent(new TestEvent());//移除一个

EventBus.getDefault().removeAllStickyEvents();//移除全部
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
(9)EventBus processor使用

关于这个东西的使用,我看了一下,哎呀,看不太懂,拜访了鸿洋大神的博客,勉强能理解一点关于这个编译时注解这个东西。。。 
要想深入了解可以点击这个 
http://blog.csdn.net/Tencent_Bugly/article/details/51354693 【腾讯Bugly干货】老司机教你“飙”EventBus3 
这里就教你怎么做就行了:

项目的build.gradle中配置

buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

app的build.gradle中配置

apply plugin: 'com.neenbedankt.android-apt'
apt {
    arguments {
        eventBusIndex "com.whoislcj.eventbus.MyEventBusIndex"
    }
}
dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

此时编译一次,自动生成生成索引类。在\build\generated\source\apt\PakageName\下看到通过注解分析生成的索引类,这样我们便可以在初始化EventBus时应用我们生成的索引了。

添加索引到EventBus默认的单例中

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();//如果你做了单例的话,放到单例中,如果没有就在Application中放上这句就行了

 
 
  • 1
  • 2
  • 1
  • 2

这玩意主要是为了提高这句代码的速度

EventBus.getDefault().register(this);
 
 
  • 1
  • 1

(10)代码的混淆

我发现好多人都为这个问题纠结,最后找不到错就直接不混淆了,呵呵呵 
先来个全的

-keepattributes *Annotation*//keep反射
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;//这个牵涉到你的需求如何,如果你使用了EventBus processor进行加速,你就必须加上这个,只要有这个注解的类和方法都不混淆,为反编译提供了便利。。。如果没有用到加速,这个就不用了
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor//如果你使用了ASYNC 异步线程
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

好了关于Eventbus的使用就这些内容,如果你想再了解一下源码,这里是传送门

http://skykai521.github.io/2016/02/20/EventBus-3-0%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/ EventBus 3.0 源代码分析 
还有这些个网址 
http://www.cnblogs.com/whoislcj/p/5595714.html Android消息传递之EventBus 3.0使用详解(三)

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EventBus是一个开源的发布/订阅事件总线库,它简化了不同组件之间的通信,避免了紧密耦合的代码。它使用了观察者模式,让不同的组件能够在没有直接关联的情况下相互通信。下面是EventBus在Android使用详解。 1.导入EventBus库 在build.gradle文件添加以下代码: ``` dependencies { implementation 'org.greenrobot:eventbus:3.2.0' } ``` 2.定义事件类 定义一个事件类,用于传递数据。 ```java public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = message; } } ``` 3.注册EventBus 在需要接收事件的组件注册EventBus。 ```java @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } ``` 4.注销EventBus 在不需要接收事件的组件注销EventBus。 ```java @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } ``` 5.发布事件 在发送事件的组件发布事件。 ```java EventBus.getDefault().post(new MessageEvent("Hello EventBus!")); ``` 6.订阅事件 在接收事件的组件订阅事件。 ```java @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) { String message = event.message; // 处理事件 } ``` 7.指定线程模式 EventBus支持在不同的线程处理事件,可以通过@Subscribe注解的threadMode参数指定线程模式。 ```java @Subscribe(threadMode = ThreadMode.MAIN) // 主线程 public void onMessageEvent(MessageEvent event) { String message = event.message; // 处理事件 } @Subscribe(threadMode = ThreadMode.BACKGROUND) // 后台线程 public void onMessageEvent(MessageEvent event) { String message = event.message; // 处理事件 } @Subscribe(threadMode = ThreadMode.ASYNC) // 异步线程 public void onMessageEvent(MessageEvent event) { String message = event.message; // 处理事件 } ``` EventBus使用非常简单,但是需要注意以下几: - 订阅方法必须使用@Subscribe注解,并且方法必须是public、void类型。 - 发布事件和接收事件的参数类型必须一致。 - 在注册EventBus时,不要忘记在onStop()方法注销EventBus,否则可能会引起内存泄漏。 - EventBus默认在主线程处理事件,如果事件处理需要耗时操作,可以使用不同的线程模式。 - EventBus不支持跨进程通信,只能在同一进程的组件之间进行通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值