如果你喜欢分享,一起加入群:524727903
特点:
- 在EventBus中,面向对象的范例适用于事件和订阅者类;假设事件类A是B的超类;类型B的发布的事件也将被发布给对A感兴趣的用户;类似地,考虑用户类的继承;
添加依赖
- compile ‘org.greenrobot:eventbus:3.0.0’
快速使用
- 声明一个标准的Java对象
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
- 声明订阅者方法,在事件发布时将被调用,使用EventBu3可以自由选择方法名称(不用像EventBus2中的命名约定)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
doSomethingWith(event);
}
在使用EventBus时我们需要注册,在不需要使用时我们可以注销掉,有点类似广播的意思
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
3.发布事件,与事件类型匹配的所有当前注册订阅者都将收到;
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
ThreadMode
可以看到上面订阅方法的注解有ThreadMode,在EventBus中ThreadMode有四种
订阅者在接受事件可以与发布线程在同一线程或者不同线程,具体配置取决于这个ThreadMode的赋值;
ThreadMode: POSTING
订阅者和发布者将处在同一个线程中(发布者在主线程中运行,订阅者就在主线程中运行),这是EventBus的默认值,事件发送时同步完成的,一单发布完成,所有订阅者都会被回调;使用此模式的事件处理程序应该快速返回,以避免阻塞发布线程,这可能是主线程;
栗子(结合EventBus特点):
// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
log(event.message);
}
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(String event) {
System.out.println("onMessage---Thread.currentThread().getName() = " + Thread.currentThread().getName()+" event = "+event);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage1(String event) {
System.out.println("onMessage1---Thread.currentThread().getName() = " + Thread.currentThread().getName()+" event = "+event);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void eventBus(View view) {
new Thread() {
@Override
public void run() {
super.run();
EventBus.getDefault().post("Hello everyone!");
System.out.println("eventBus---Thread.currentThread().getName() = " + Thread.currentThread().getName());
}
}.start();
}
}
public class BaseActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage2(String event) {
System.out.println("onMessage2---Thread.currentThread().getName() = " + Thread.currentThread().getName()+" event = "+event);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
可以对照事件、线程名来总结;
这里发现,不仅调用了MainActivity还调用了BaseActivity;
ThreadMode: MAIN
订阅者会在UI线程中运行,使用此模式的事件处理程序必须快速返回以避免阻塞主线程。
栗子:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
栗子代码:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMain(Integer i){
System.out.println("onMain---Thread.currentThread().getName() = " + Thread.currentThread().getName()+" i = "+i);
}
public void eventBus(View view) {
new Thread() {
@Override
public void run() {
super.run();
EventBus.getDefault().post(new Integer(100));
System.out.println("eventBus---Thread.currentThread().getName() = " + Thread.currentThread().getName());
}
}.start();
}
不管post在哪个线程,订阅者都会在主线程中运行,所以不要运行太耗时的东西,避免ANR。
ThreadMode: BACKGROUND
如果post在主线程,那么订阅者开辟一个后台线程接受事件
如果post在非主线程,那么订阅者和传递者在同一线程
// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
saveToDisk(event.message);
}
ThreadMode: ASYNC
订阅者在单独的线程中处理,与post时的线程和主线程无关,主要执行一些需要耗时的操作;例如 用于网络访问;
栗子:
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
backend.send(event.message);
}
public void onMain(Integer i) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("onMain---Thread.currentThread().getName() = " + Thread.currentThread().getName() + " i = " + i);
}
public void eventBus(View view) {
new Thread() {
@Override
public void run() {
super.run();
EventBus.getDefault().post(new Integer(3000));
}
}.start();
System.out.println("eventBus---Thread.currentThread().getName() = " + "1111111111111111");
}
参考文献:
EventBus官网