事件总线EventBus框架的使用介绍

事件总线EventBus框架的使用介绍

.

EventBus

介绍

EventBus是一款针对Android优化的发布-订阅事件总线。它简化了应用程序内各组件间、组件与后台线 程间的通信。其优点是开销小,代码更优雅,以及将发送者和接收者解耦。

.

EventBus 的三要素

  1. Event: 事件,可以是任意类型的对象

  2. Subscriber: 事件订阅者,在 EventBus 3.0 之前我们必须定义以onEvent开头的那几个方法,分别是 onEventonEventMainThreadonEventBackgroundThreadonEventAsync,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe,并且指定线程模型,默认是POSTING。

  3. Publisher: 事件发布者,可以在任意线程任意位置发送事件, 直接调用。一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可

.

四种线程模型

EventBus3.0有四种线程模型,分别是:

  • POSTING(默认): 表示事件处理函数的线程跟发布事件的线程在同一个线程

  • MAIN: 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作

  • BACKGROUND: 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程

  • ASYNC: 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作

可以在 处理事件 的时候来设置线程模型,如下所示:

//设置线程模型
@Subscribe(threadMode = ThreadMode.MAIN)
public void XXXX(MessageWrap message) {
    
    
    //消息的内容
	Log.d("接收的信息内容:",message);
}

.

.

EventBus基本用法

引入依赖

在使用之前先要在build.gradle引入如下依赖:

dependencies{
    
    
	implementation 'org.greenrobot:eventbus:3.1.1'
}

.

EventBus使用起来分为以下5个步骤:

.

1. 自定义一个事件类

作用: 在程序内部就使用该对象作为通信的信息

public class MessageEvent {
    
    

    public final String message;

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

    public static MessageEvent getInstance(String message) {
    
    
        return new MessageWrap(message);
    }
}

2. 在需要订阅事件的地方注册事件

在MainActivity中注册事件,如下所示:

public class MainActivity extends AppCompatActivity{
    
    

	@Override
	protected void onCreate (Bundle savedInstanceState){
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_,ain);
		
		initData();
	}

	public vaid init(){
    
    
		//注册事件
		EventBus.getDefault().register(this);
	}
}

3. 发送事件

创建了SecondActivity来发布消息,代码如下所示:

public class SecondActivity extends AppCompatActivity{
    
    

	@Override
	protected void onCreate (Bundle savedInstanceState){
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_,ain);
		
		sendMessag();
	}

	public vaid sendMessag(){
    
    
		//发送消息
		EventBus.getDefault().post(new MessageEvent("你好!我是萝莉"));
	}
}

4. 在事件接收方处理事件

在MainActivity中接收事件并进行修改的处理,如下所示:

public class MainActivity extends AppCompatActivity{
    
    

	@Override
	protected void onCreate (Bundle savedInstanceState){
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_,ain);
		
		initData();
	}

	public vaid init(){
    
    
		//注册事件
		EventBus.getDefault().register(this);
	}

	@Subscribe(threadMode = ThreadMode.MAIN)
	public void GetMessage(MessageWrap message) {
    
    
        //打印消息的内容
		Log.d("接收的信息内容:",message);
	}
}

5. 取消事件订阅

在MainActivity的 onDestroy() 方法中取消订阅事件,如下所示:

public class MainActivity extends AppCompatActivity{
    
    

	@Override
	protected void onCreate (Bundle savedInstanceState){
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_,ain);
		
		initData();
	}

	public vaid init(){
    
    
		//注册事件
		EventBus.getDefault().register(this);
	}

	@Subscribe(threadMode = ThreadMode.MAIN)
	public void GetMessage(MessageWrap message) {
    
    
        //打印消息的内容
		Log.d("接收的信息内容:",message);
	}

	@Override
	protected void onDestroy(){
    
    
		super.onDestroy();
		//取消注册事件
		EventBus.getDefault().unregister(this);
	}
}

6. 添加 ProGuard 混淆规则

proguard-rules.pro 文件添加混淆规则

#eventbus打包混淆
- keepattributes *Annoation*
- keepclassmembers class **{
    
    
	@org.greenrobot.eventbus.Subscrile<methods>;
}

-keep enum org.greenrobot.eventbus.ThreadMode{
    
     *; }
# Only requirend if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.
ThrowableFailurEvent{
    
    
	<init>(java.lang.Throwable);
}

.

.

EventBus的黏性事件的介绍

EventBus还支持发送黏性事件,就是在发送事件之后再订阅该事件也能收 到该事件,这跟黏性广播类似。

.

为了验证黏性事件,我们修改以前的代码,如下所示

1. 订阅者处理黏性事件

在MainActivity中新写一个方法用来处理黏性事件

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void GetViscosityMessage(MessageWrap message) {
    
    
    //打印消息的内容
	Log.d("接收的黏性信息内容:",message);
}

2. 发送黏性事件

在SecondActivity发送黏性事件

public vaid sendMessag(){
    
    
	//发送消息
	EventBus.getDefault().postSkticky(new MessageEvent("你好!我是萝莉"));
}

.

.

EventBus订阅优先级的介绍

Subscribe注解 中总共有3个参数,其中 priority参数用来指定订阅方法的优先级,是一个整数类型的值,默认是0,值越大表示优先级越大。在某个事件被发布出来的时候,优先级较高的订阅方法会首先接受到事件。

使用:

@Subscribe(threadMode = ThreadMode.POSTING, priority = 0)

注意:

  • 只有当两个订阅方法使用相同的ThreadMode参数的时候,它们的优先级才会与priority指定的值一致

  • 只有当某个订阅方法的ThreadMode参数为POSTING的时候,它才能停止该事件的继续分发

具体使用:

public class MainActivity extends AppCompatActivity{
    
    

	// 用来判断是否需要停止事件的继续分发
	private boolean stopDelivery = false;

	@Override
	protected void onCreate (Bundle savedInstanceState){
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_,ain);
		
		initData();
	}

	public vaid init(){
    
    
		//注册事件
		EventBus.getDefault().register(this);
	}

	/*-------------------- 对事件进行处理 --------------------*/
	@Subscribe(threadMode = ThreadMode.POSTING, priority = 0)
	public void onGetMessage(MessageWrap message) {
    
    
      	//打印消息的内容
		Log.d("接收的信息内容:",message);
	}

	// 订阅方法,需要与上面的方法的threadMode一致,并且优先级略高
	@Subscribe(threadMode = ThreadMode.POSTING, sticky = true, priority = 1)
	public void onGetStickyEvent(MessageWrap message) {
    
    
		//打印消息的内容
		Log.d("接收的信息内容:",message);			

	    if (stopDelivery) {
    
    
	        // 终止事件的继续分发
	        EventBus.getDefault().cancelEventDelivery(message);
	    }
	}

	@Override
	protected void onDestroy(){
    
    
		super.onDestroy();
		//取消注册事件
		EventBus.getDefault().unregister(this);
	}
}

.

.

补充:

用RxJava实现RxBus

如果你的项目中已经引入RxJava ,那么可以用 RxJava 来实现事件总线 RxBus,以替代EventBus和 otto。

引入依赖

在使用之前先要在build.gradle引入如下依赖:

dependencies{
    
    
	implementation 'io.reactivex:rxjava:1.2.0'
	implementation 'io.reactivex:rxandroid:1.2.1'
}

1. 创建RxBus

首先创建RxBus。这里的RxBus只是支持基本的功能,读者如果想要添加一些功能,则可以自定义添加,代码如下所示:

public class RxBus{
    
    
	private static volatile RxBus rxBus;
	private final Subject<Object,Object> subject = new SerializedSubject<>(PublishSubject.create);

	//使用单例模式的双重检查模式
	public static RxBus getInstance(){
    
    
		if(rxBus == null){
    
    
			synchronized(RxBus.class){
    
    
				if(rxBus == null){
    
    
					rxBus = new RxBus();
				}
			}
		}
		return rxBus;
	}

	public void post(Object ob){
    
    
		subject.onNext(ob);
	}

	public <T> Observable<T> toObservable(Class<T> eventType){
    
    
		//ofType方法中包含了filter和cast的操作。
		//通过filter操作符来判定是否是指定的类型,如果不是就不提交 给订阅者。
		//cast操作符则用来将Observable转换成指定类型的Observable
		return subject.ofType(eventType);
	}

}

2. 发送事件

在MainActivity 中发送事件

public class MainActivity extends AppCompatActivity{
    
    

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

	public vaid init(){
    
    
		//发送事情
		RxBus.getInstance().post(new MessageEvent("用RxJava实现RxBus"));
	}
}

3. 接收事件

在TwoActivity中接收事件,如下所示:

public class TwoActivity extends AppCompatActivity{
    
    
	
	private Subscriber subscription;
	
	@Override
	protected void onCreate (Bundle savedInstanceState){
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_two);
		
		initData();
	}

	public vaid init(){
    
    
		//接收消息
		subscription = RxBus.getInstance.toObservable(MessageEvent.class).subscribe(new Action1<MessageEvent>(){
    
    
		@Override
		public void call(MessageEvent messageEvent){
    
    
			Log.v("MainActivity发送过来的消息:",messageEvent.getMessage());
			}
		}
	}

	@Override
	protected void onDestroy(){
    
    
		super.onDestroy();
		//取消订阅事件
		if(subscription != null && !subscription.isUnsubscribed()){
    
    
			subscription.unsubscribe();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42324979/article/details/112172736