事件驱动开发
最近android的事件驱动开发风靡一时,一夜之间似乎所有人都在搞这个东西,这里我就记录一下我是怎么把我的应用(TT日程管理)重构为事件驱动模式的。
前言
首先呢,最主要的,就是eventbus,github地址,类似的一个开源项目是otto,github地址,不过我看了好多文章,似乎说otto性能上不如eventbus好。所以我权且使用eventbus吧。
非事件驱动模式的开发
众所周知的,我们在开发过程中会遇到这样的问题,我们在后台获取数据(一般来说是耗时的操作),这时候我们会新起线程,在非UI线程中获取数据,然后通过主线程的handler更新UI。所以会有如下代码:
new Thread(new Runnable() {
@Override
public void run() {
//do something
handler.sendMessage(new Message());
}
}).start();
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
//更新UI
};
};
代码看上去还行,但是!如果是在一个比较大的项目中,每一个耗时操作都用如上方式,你就会发现很多缺点,比如:
- 你的handler实在太多,而且不好管理
- 容易内存泄漏(这里有一种方式是可以防止内存泄漏的:点这里)
- 在不同类中你还会发现调用实在不方便(这个其实也有办法,就是自己写一个handler管理类)
- 最重要的,就是项目结构特别难看,没有有效的组织。
当然,缺点不止于此。
事件驱动开发
现在,我用eventbus来重构我的应用
项目结构
UI主要负责显示部分,service负责处理数据,通知中心负责转发通知。
流程为:UI向service发送数据请求,service经过耗时处理告诉通知中心:数据请求好了,并将请求的数据传递给通知中心,通知中心将消息告诉UI,UI把通知中心转发的处理好的数据进行展示。
注:实际上,UI是作为一个观察者,而通知中心作为被观察者
具体代码
1.service(这里是指数据处理服务,不是android的服务组件)
public class ServiceProvider {
public static void provide() {
new Thread(new Runnable() {
@Override
public void run() {
//耗时操作获取到data数据
//通知到通知中心
EventCenter.notifyResult(data);
}
}).start();
}
}
2.通知中心
public class EventCenter {
public static void notifyResult(Data data) {
EventBus.getDefault().post(new Event(data));
}
这里有一个类,叫做event,事件类,它作为一个通知的载体而存在
public class Event {
private Data mData;
public SearchEvent(Data data) {
this.mData = data;
}
public Data getData() {
return mData;
}
}
3.UI
以activity为例
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
public void onEventMainThread(Event event) {
Log.i("onEventMainThread",event.getData());
}
}
在activity生命周期起始位置注册,在结束位置注销(观察者模式必须有注销,防止内存泄漏),onEventMainThread这个方法为通知中心通知到的方法,当然不一定是这个名称,其实可以自定义,具体看eventbus源码。在这个方法中获取event携带的数据,并刷新UI。
经过这一次重构,明显能感觉到app的结构优化了很多,当然,对于性能的影响我暂时没有进行测试,不过使用过程中没有感觉到有变化。