事件驱动开发


最近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的结构优化了很多,当然,对于性能的影响我暂时没有进行测试,不过使用过程中没有感觉到有变化。