EventBus3.0 使用个人总结

文章参考文章如下:

 * http://www.jianshu.com/p/4fa4c7205613

 * http://blog.csdn.net/angcyo/article/details/48166849

 * http://blog.csdn.net/harvic880925/article/details/40660137

 * http://www.tuicool.com/articles/FBbMnay

EventBus的github地址:https://github.com/greenrobot/EventBus


一、什么是EventBus

EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。


二、怎么用

前提:如果是as直接添加依赖

compile 'de.greenrobot:eventbus:3.0.0-beta1'
         如果还是eclipse的话,需要下载jar包,可以到这个网站  http://search.maven.org/#search%7Cga%7C1%7Ceventbus上下载,导入lib包即可,我这里下载的是 3.0正式版,点击可以下载

1、注册和注销监听,在activity的2个方法中添加如下

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

}

 

2、自定义一个消息类,这个就是发布的事件

public class FirstEvent {

	private String mMsg;//消息内容
	private String tag; //消息类型
	
	public FirstEvent(String mMsg, String tag) {
		super();
		this.mMsg = mMsg;
		this.tag = tag;
	}
	public String getTag() {
		return tag;
	}
	public void setTag(String tag) {
		this.tag = tag;
	}
	public FirstEvent(String msg) {
		mMsg = msg;
	}
	public String getMsg(){
		return mMsg;
	}
}

3、绑定方法,又叫订阅事件,就是你要怎么处理这个消息,方法名在3.0版本可以随意取,但是要添加注释Subscribe

@Subscribe(threadMode = ThreadMode.MainThread)
public void helloEventBus(FirstEvent message){
    mText.setText(message);
}


备注:注释后面可以添加3个参数 threadMode   stick   priority

 ThreadMode.MAIN,事件接收函数执行在UI线程;

ThreadMode.POST,事件在哪个线程发布,接收函数就执行在哪个线程;默认

ThreadMode.ASYNC,事件执行在一个独立的异步线程中。强制在后台执行

ThreadMode.BackgroundThread,如果事件是在UI线程中发布出来的,那么就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么直接在该子线程中执行。


//如果由于事件的发布者是在子线程中,所以BACKGROUND与POSTING模式下订阅者与事件的发布者运行在同一个线程。

//而ASYNC模式下又重新开起一个线程来执行任务。Main模式则是在主线程中运行


priority:默认值为0。订阅了同一个事件的订阅函数,在ThreadMode值相同的前提下,收到事件的优先级,值越大优先级越高。


sticky = true  默认情况下,其为false。什么情况下使用sticky呢?

当你希望你的事件不被马上处理的时候,举个栗子,比如说,在一个详情页点赞之后,产生一个VoteEvent,VoteEvent并不立即被消费,而是等用户退出详情页回到商品列表之后,接收到该事件,然后刷新Adapter等。其实这就是之前我们用startActivityForResult和onActivityResult做的事情。


4、发布事件

EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked","1"));

备注

1.事件被post后哪个事件的监听者会响应的问题,这个取决于你写的监听方法所跟的参数类型。如果方法后面的参数是一样的,则所有的方法都会执行。(比如例子里面我post的是一个FirstEvent的对象,则接收方法里所有参数是FirstEvent的函数都会执行

2.你写的事件监听方法得是public修饰的,如果你写成private了,则不会收到消息。

3.问:当你post了消息之后,你的订阅者有多个,每一个都接收吗?能否做到指定接收者。这个目前有没好的方法?

      答:所谓观察者模式,即生产者无需知道其消费者,既然其订阅了该消息,就应该为其发送消息,所以你指的指定接收者,违背了其设计。

但是我又很想指定某个接收者,所以我在对象里多添加了一个tag参数,虽然所有函数都会触发,但我可以指定某些特定条件的代码会执行。一会看例子。


例子

1、我有2个activity,在第2个ac里发送数据,在第1个ac里显示发送的数据

public class MainActivity extends Activity {

	Button btn;
	TextView tv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_eventbus1);
		  //注册EventBus  
		EventBus.getDefault().register(this);
		btn = (Button) findViewById(R.id.btn_try);
		tv = (TextView)findViewById(R.id.tv);

		btn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				
				Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
				startActivity(intent);
			}
		});
	}
	
	/**
	 * 用这个函数来接收消息
	 * @param event 自己定义的类
	 */
	@Subscribe(threadMode = ThreadMode.MAIN)
	public void receiveMsg(FirstEvent event){
		String tag=event.getTag();
		if(tag!=null&&!TextUtils.isEmpty(tag)){
			Log.i("hemiy", "收到了tag的消息");
		}else{
			String msg = "BACKGROUND收到了消息" + event.getMsg();
			tv.setText(msg);
			Log.i("hemiy", "不是tag的消息");
			Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
		}
	}
	
	@Subscribe(threadMode = ThreadMode.POSTING)
	public void receiveMsg1(FirstEvent event){
		String tag=event.getTag();
		if(tag!=null&&!TextUtils.isEmpty(tag)){
			Log.i("hemiy", "收到了tag的消息");
		}else{
			
			String msg = "BACKGROUND收到了消息" + event.getMsg();
			tv.setText(msg);
			Log.i("hemiy", "不是tag的消息");
			Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
		}
	}
	
	@Subscribe(threadMode = ThreadMode.BACKGROUND)
	public void receiveMsg2(FirstEvent event){
		String tag=event.getTag();
		if(tag!=null&&!TextUtils.isEmpty(tag)){
			Log.i("hemiy", "收到了tag的消息");
		}else{
			
			String msg = "BACKGROUND收到了消息" + event.getMsg();
			tv.setText(msg);
			Log.i("hemiy", "不是tag的消息");
			Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
		}
	}
	
	@Subscribe(threadMode = ThreadMode.ASYNC)
	public void receiveMsg3(FirstEvent event){
		String tag=event.getTag();
		if(tag!=null&&!TextUtils.isEmpty(tag)){
			Log.i("hemiy", "收到了tag的消息");
		}else{
			
			String msg = "BACKGROUND收到了消息" + event.getMsg();
			tv.setText(msg);
			Log.i("hemiy", "不是tag的消息");
			Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
		}
	}
	
	@Override
	protected void onDestroy(){
		super.onDestroy();
		//反注册EventBus  
		EventBus.getDefault().unregister(this);
		
		//或者这么写
		/*if(EventBus.getDefault().isRegistered(this)){
			EventBus.getDefault().unregister(this);
		}*/
		
	}
}

MainActivity的xml布局如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
 >

  <Button 
        android:id="@+id/btn_try"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="进入第2个ac"/>
    <TextView 
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"/>

</LinearLayout>




接下来是第2个activity

package eventbus;

import org.greenrobot.eventbus.EventBus;

import com.example.hemiydemo.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class SecondActivity extends Activity {
	private Button btn_FirstEvent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_eventbus2);
		btn_FirstEvent = (Button) findViewById(R.id.btn_first_event);
		btn_FirstEvent.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
            //	发送消息是使用EventBus中的Post方法来实现发送的,发送过去的是我们新建的类的实例!
				EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked"));
			}
		});


	}
	
	public void sendForOne(View view){
		EventBus.getDefault().post(new FirstEvent("指定发送","1"));
	}

}
其xml布局如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
 >

<Button 
        android:id="@+id/btn_first_event"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送事件,全体发送"/>

<Button 
        android:onClick="sendForOne"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送事件,指定发送"/>

</LinearLayout>

说明

1、在secondActivity有2个Button,点击这2个按钮,则MainActivity里面所有的4个接收函数都会触发。因为它们的参数都是FirstEvent。区别就是4个方法执行的线程不同。

2、我在FirstEvent里指定不同的tag,则可以执行特定条件下的代码。也算是指定发送了。






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值