您的位置:首页 > 其它

EventBus3.0 使用个人总结

2016-05-22 19:47 411 查看
文章参考文章如下:
* 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包即可,我这里下载的是 href="http://download.csdn.net/download/qq_28746251/9527894" target=_blank>3.0正式版,点击可以下载

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

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

}
<p class="p1"><span class="s1">protected</span> <span class="s1">void</span> onDestroy(){</p><p class="p1"><span>	</span><span>	</span><span class="s1">super</span>.onDestroy();</p><p class="p2"><span class="s2"><span>	</span><span>	</span></span>//反注册EventBus  </p><p class="p1"><span>	</span><span>	</span>EventBus.getDefault().unregister(<span class="s1">this</span>);<span style="font-family: Arial, Helvetica, sans-serif;">	</span></p><p class="p2"><span class="s2"><span>	</span><span>	</span></span>//或者这么写</p><p class="p2"><span class="s2"><span>	</span><span>	</span></span>/*if(EventBus.getDefault().isRegistered(this)){</p><p class="p2"><span>	</span><span>	</span><span>	</span>EventBus.getDefault().unregister(this);</p><p class="p2"><span>	</span><span>	</span>}*/<span style="font-family: Arial, Helvetica, sans-serif;">	</span><span style="font-family: Arial, Helvetica, sans-serif;">	</span></p><p class="p1"><span>	</span>}</p>



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,则可以执行特定条件下的代码。也算是指定发送了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: