EventBus3.0 传参框架的简单使用
Demo : 点击按钮3秒后更新Activity界面的textView的数据
要求: 这个数据由消息携带
- 官方网站
- 简单介绍
- 代码实现步骤
- 完整代码
- 坑一 Subscriber class com.eventbusdemo.activities.MainActivity$2 and its super classes have no public methods with the @Subscribe annotation
- 坑二 Subscriber class comeventbusdemo.activities.MainActivity already registered to event class com.fu.mr.eventbusdemo.MessageEvent
官方网站
https://github.com/greenrobot/EventBus
简单介绍
基于发布订阅模型的一个传参框架
可以将任意类型的参数(Object)传递给任意组件 (activity fragment adapter service 等。。。)
代码实现步骤
1 添加依赖
compile 'org.greenrobot:eventbus:3.0.0'
2 编写传递数据的方法
private void addListener() {
mBtnUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run() {
try {
Thread.sleep(3000);
Message message = new Message();
message.obj = "My name is Mr.Fu";
EventBus.getDefault().post(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
});
}
3 以Activity为例,执行注册与移除方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
addListener();
EventBus.getDefault().register(this);
}
4 编写接收参数的方法
方法必须有@Subscribe标注
明确指定当前线程 threadMode = ThreadMode.MAIN 。默认threadMode = ThreadMode.POSTING,即跟post方法的线程一致
方法参数类型与post发送的类型一致才能接收
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventUpdateText(Message msg) {
String result = (String) msg.obj;
mTvResult.setText(result);
}
完整代码
package com.fu.mr.eventbusdemo;
import android.os.Bundle;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class MainActivity extends AppCompatActivity {
private Button mBtnUpdate;
private TextView mTvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
addListener();
EventBus.getDefault().register(this);
}
private void initView() {
mBtnUpdate = (Button) findViewById(R.id.btn_updata);
mTvResult = (TextView) findViewById(R.id.tv_result);
}
private void addListener() {
mBtnUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run() {
try {
Thread.sleep(3000);
Message message = new Message();
message.obj = "My name is Mr.Fu";
EventBus.getDefault().post(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventUpdateText(Message msg) {
String result = (String) msg.obj;
mTvResult.setText(result);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
坑一:
通过点击 Button 实现注册订阅事件操作时,在 register()方法中,直接传入 this
mBtnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().register(this); // 使用this报错, 疑似 this代表这个按钮 v
}
});
这时报错如下:
org.greenrobot.eventbus.EventBusException:
Subscriber class com.eventbusdemo.activities.MainActivity$2 and its super classes have no public methods with the @Subscribe annotation
原因 —>>> 疑似是 this指向的是这个按钮 Button
解决方法1:
mBtnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().register(当前Activity.this); // 直接使用 当前Activity.this
}
});
解决方法2:
mBtnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
registerEventBus(); // 抽取成一个独立的方法
}
});
private void registerEventBus() {
// 注册订阅事件
EventBus.getDefault().register(this); // 这时 this 指向当前类(当前Activity)
}
坑二:
mBtnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().register(当前Activity.this); // 直接使用 当前Activity.this
}
});
重复点击按钮程序崩溃,报错如下:
org.greenrobot.eventbus.EventBusException:
Subscriber class comeventbusdemo.activities.MainActivity already registered to event class com.fu.mr.eventbusdemo.MessageEvent
already registered to event class
所以为了避免这个情况,可以添加判读操作 isEventBusRegistered() ,解决如下:
/**
* 判断是否已经进行 EventBus 的注册操作
* @return
*/
private boolean isEventBusRegistered() {
return EventBus.getDefault().isRegistered(MainActivity.this);
}
注册订阅事件操作
mBtnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
registerEventBus();
// EventBus.getDefault().register(this); // 使用this报错, 疑似 this代表这个按钮 v
}
});
/**
* 实现 EventBus 的注册订阅事件操作
*/
private void registerEventBus() {
if (!isEventBusRegistered()) {
// 注册订阅事件
EventBus.getDefault().register(MainActivity.this);
Toast.makeText(MainActivity.this,
"注册事件完成", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this,
"已经注册事件,无需再次注册", Toast.LENGTH_SHORT).show();
}
}
取消事件订阅操作
mBtnUnregister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unregisterEventBus();
}
});
/**
* 实现 EventBus 取消事件订阅操作
*/
private void unregisterEventBus() {
if (isEventBusRegistered()) {
// 取消事件订阅
EventBus.getDefault().unregister(MainActivity.this);
Toast.makeText(MainActivity.this,
"取消事件订阅完成", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this,
"未注册事件,无需取消事件订阅", Toast.LENGTH_SHORT).show();
}
}
而且在以上的独立方法中,直接使用 this 代替 MainActivity.this 也是可以的,不会报错
----------只要你愿意,性格随时随地可以改变----------