事件驱动开发
2015-05-29 12:45
405 查看
本文首先发表在http://www.hikyson.cn/archives/651
最近android的事件驱动开发风靡一时,一夜之间似乎所有人都在搞这个东西,这里我就记录一下我是怎么把我的应用(TT日程管理)重构为事件驱动模式的。
代码看上去还行,但是!如果是在一个比较大的项目中,每一个耗时操作都用如上方式,你就会发现很多缺点,比如:
你的handler实在太多,而且不好管理
容易内存泄漏(这里有一种方式是可以防止内存泄漏的:点这里)
在不同类中你还会发现调用实在不方便(这个其实也有办法,就是自己写一个handler管理类)
最重要的,就是项目结构特别难看,没有有效的组织。
当然,缺点不止于此。
UI主要负责显示部分,service负责处理数据,通知中心负责转发通知。
流程为:UI向service发送数据请求,service经过耗时处理告诉通知中心:数据请求好了,并将请求的数据传递给通知中心,通知中心将消息告诉UI,UI把通知中心转发的处理好的数据进行展示。
注:实际上,UI是作为一个观察者,而通知中心作为被观察者
2.通知中心
这里有一个类,叫做event,事件类,它作为一个通知的载体而存在
3.UI
以activity为例
在activity生命周期起始位置注册,在结束位置注销(观察者模式必须有注销,防止内存泄漏),onEventMainThread这个方法为通知中心通知到的方法,当然不一定是这个名称,其实可以自定义,具体看eventbus源码。在这个方法中获取event携带的数据,并刷新UI。
经过这一次重构,明显能感觉到app的结构优化了很多,当然,对于性能的影响我暂时没有进行测试,不过使用过程中没有感觉到有变化。
最近android的事件驱动开发风靡一时,一夜之间似乎所有人都在搞这个东西,这里我就记录一下我是怎么把我的应用(TT日程管理)重构为事件驱动模式的。
前言
首先呢,最主要的,就是eventbus,github地址,类似的一个开源项目是otto,github地址,不过我看了好多文章,似乎说otto性能上不如eventbus好。所以我权且使用eventbus吧。非事件驱动模式的开发
众所周知的,我们在开发过程中会遇到这样的问题,我们在后台获取数据(一般来说是耗时的操作),这时候我们会新起线程,在非UI线程中获取数据,然后通过主线程的handler更新UI。所以会有如下代码:[code] new Thread(new Runnable() { @Override public void run() { //do something handler.sendMessage(new Message()); } }).start();
[code] 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的服务组件)[code] public class ServiceProvider { public static void provide() { new Thread(new Runnable() { @Override public void run() { //耗时操作获取到data数据 //通知到通知中心 EventCenter.notifyResult(data); } }).start(); } }
2.通知中心
[code] public class EventCenter { public static void notifyResult(Data data) { EventBus.getDefault().post(new Event(data)); }
这里有一个类,叫做event,事件类,它作为一个通知的载体而存在
[code] public class Event { private Data mData; public SearchEvent(Data data) { this.mData = data; } public Data getData() { return mData; } }
3.UI
以activity为例
[code] 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的结构优化了很多,当然,对于性能的影响我暂时没有进行测试,不过使用过程中没有感觉到有变化。
相关文章推荐
- jquery.pagination结合jquery.tmpl封装前台分页--纯js实现与后端语言无关--适合所有前台分页情况
- 微信之门-授权接口
- jstl、EL跟OGNL
- hdu3577 Fast Arrangement
- MyEclipse 2015优化技巧
- Unity3D单例管理类
- POj 2041 Constructing Roads
- chrome开发人员工具中出现绿色的矩形框解决
- 几款开源前端绘图插件推荐
- HDU 2086 A1 = ?
- Linux下tcp协议socket的recv函数返回时机分析(粘包)
- 集成支付宝SDK时错误的解决办法
- java虚拟机精讲 读后
- T-SQL语句中中括号([])的用法是什么,什么时候该用
- 模型选择
- 编写Python脚本把sqlAlchemy对象转换成dict的教程
- arch使用create_ap创建wifi热点
- 适用于多种设备的的滑块幻灯片插件--jquery插件Swiper
- Lucas定理应用分析——大组合数取模
- Java实现Socket的TCP传输实例