今天看了下EventBus的实现,感觉好用又高大上,简洁又实惠
最开始以为只是能简单地BrocastReceiver发简单的通知而已,然而后面发现功能不只是只有这么一点点,感觉发现了新大陆
我发现它在应用到网络请求这块可以让你看不到请求网络的逻辑是啥,callBack也没有了,整个代码清晰明朗
现在我来使用EventBus模拟一下一般的带参数的网络请求,让你几分钟内爱上他
开始啦,我们模拟一个场景
Activity里面有个按钮,点击就去加载数据,数据加载完就显示到Fragment里面
界面很简单,就不贴代码了
那好,现在我们开始引入EventBus
gredle里面依赖EventBus
compile 'de.greenrobot:eventbus:3.0.0-beta1'
compile 'de.greenrobot:eventbus-annotation-processor:3.0.0-beta1'//优化性能
同步一下就ok啦
我们知道BrocastReceiver发送广播是根据intentFilter来过滤的,那EventBus也得有个过滤的吧?
没错,这家伙的过滤其实就是接收消息时的类名
首先我们新建一个处理网络请求的类,这边叫做RequestData
public class RequestData {
public RequestData() {
EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.BackgroundThread)
public void requestFromNet(RequestEntry entry) {
//做了一些网络的请求~~~~~~
Log.e("requestFromNet", entry.toString());
try {
Thread.sleep(3000); //用休眠模拟网络请求
postResult(new ResultEntry(200, "good", "你是狗~~~"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void postResult(ResultEntry requestEntry) {
EventBus.getDefault().post(requestEntry);
unRegisterEvent();
}
private void unRegisterEvent() {
EventBus.getDefault().unregister(this);
}
}
里面有两个类,一个是请求数据的参数类,一个是数据返回时的数据包装类,我们这边简单做一下模拟
说明一下,这个类里面有两个主要方法,一个是接收到消息以后做网络请求,一个是网络请求成功后发消息通知UI更新
首先我们在构造方法里面注册了EventBus,在收到请求结果后发送通知给UI界面,然后反注册EventBus,因为网络请求是耗时操作,所以使用 @Subscribe(threadMode=ThreadMode.BackgroundThread)的方式
其实requestFromNet是注册的监听接收到别人的消息时做的操作,postResult是自己发通知给别人需要别人做响应的动作,下面是模拟的两个类
RequestEntry
public class RequestEntry {
String url;
String method;
String parmar;
public RequestEntry(String url, String method, String parmar) {
this.url = url;
this.method = method;
this.parmar = parmar;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getParmar() {
return parmar;
}
public void setParmar(String parmar) {
this.parmar = parmar;
}
@Override
public String toString() {
return "RequestEntry{" +
"url='" + url + '\'' +
", method='" + method + '\'' +
", parmar='" + parmar + '\'' +
'}';
}
}
ResultEntry
public class ResultEntry {
int code;
String msg;
String data;
public ResultEntry(int code, String msg, String data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
重点是哪个RequestData类,好了,网络请求类做好了,下面我们来看看Activity和Fragment怎么做操作和响应操作
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RequestData requestData = new RequestData();
getSupportFragmentManager().beginTransaction().add(R.id.container, new BlankFragment()).commit();
}
public void postMsg(View view) {
RequestEntry result = new RequestEntry("www.google.com", "get", "go die");
EventBus.getDefault().post(result);
}
}
我们在Activity里面就做了一个按钮,点击就发送Event事件让RequestData类去执行请求数据操作,就这个操作而已
public class BlankFragment extends Fragment {
private TextView tvText;
public BlankFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
EventBus.getDefault().register(this);
View view = inflater.inflate(R.layout.fragment_blank, container, false);
tvText = (TextView) view.findViewById(R.id.textView);
return view;
}
@Subscribe(threadMode = ThreadMode.MainThread)
public void say(ResultEntry message) {
tvText.setText(message.getData());
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
Fragment做两件事,一件是注册EventBus,另一件就是注册监听,当RequestData请求完数据后就会发一个post,此时这边就会收到消息,然后显示,因为是显示数据到UI,所以要使用
@Subscribe(threadMode = ThreadMode.MainThread)
我们画个示意图
Activity的按钮点击是发一个post给RequestData,数据类型是RequestEntry,此时requestFromNet的参数跟activity的post的参数一致,就会调用此方法,开始请求数据,参数请求完也会发送一个post,将ResultEntry发送出去,此时Fragment里面注册的
public void say(ResultEntry message) {
tvText.setText(message.getData());
}
方法就会被触发
备注下:
在这个场景中,需要注册EventBus的有RequestData和Fregment,Activity只是发消息而已,如果是在复杂的项目中,一般将RequestData的初始化放在BaseActivity里面,就不用每次都要实例化
最后来梳理一下EventBus的使用
使用EventBus,首先需要初始化
EventBus.getDefault().register(this);
发送消息
EventBus.getDefault().post(Object result);
接收消息的类需要注册EventBus,然后使用
@Subscribe(threadMode = ThreadMode.MainThread)
public void say(ResultEntry message) {
tvText.setText(message.getData());
}
声明方法,方法名无所谓,参数类似intentFilter,EventBus。post的参数跟这边参数一致的就会触发
ThreadMode是个枚举类,
有四种方式,我就清楚MainThread和Background两种,另外两种后面再研究
mainthread线程即UI线程,处理UI
background线程用来处理耗时操作,如网络请求
那就这样
发现的新技能了,这个代码的格式很赞啊~~