观察者模式在Android中的应用
2016-01-05 17:15
429 查看
观察者模式在实际使用中是非常方便的,简单来说就是当一个数据源(即被观察者)的数据发生了变动,将自动通知到所有对应的观察者,此时观察者可以根据接收到的通知信息针对数据变动作出相应调整。
举个简单的在Android上的例子,我使用一个Service在后台进行时间倒计时,而我需要在多个Activity上同步显示该倒计时的信息。那么,Service上的倒计时功能即为被观察者(Observable),而这多个Activity则为观察者(Observer)。
Java自身带有Observable和Observer的接口,我们也可以自己自定义实现Observable和Observer,但是这就要求我们自己在Observable中维护Observer的列表。
首先,我们定义好观察者Observer的接口:
然后定义被观察者Observable的接口:
然后通过继承Observable的接口,自定义我们自己的被观察者类:
这是为了在Service以外的地方动态添加和删除观察者,写得比较简单粗暴,在实际应用过程中我们也可以根据需求进行不同的自定义。
然后,通过对Activity实现观察者Observer接口中的updata方法,并将自身通过GlobalAddObserver加入到观察者列表中。
这样,在后台Service里的倒计时功能中调用notifyObservers方法,通知所有在观察者列表中的观察者,并将数据传递到updata方法中,就完成了一次数据更新。
一般而言这样就可以了,但是偶尔会遇到一些情况,就是某个观察者的updata方法中耗时过长,这样会导致排在该观察者后面的其余观察者的无法及时更新数据。针对这个问题,我们可以用Handler来进行异步处理。
通过实现Observer接口,我们自定义一个可以异步处理的TimeCountObserver:
然后在Activity中就无需实现Observer接口,而是实例化TimeCountObserver,并且通过onUpdate方法更新数据:
效果如下图所示:
该例子的下载地址如下:
http://download.csdn.net/detail/vite_s/9391248
举个简单的在Android上的例子,我使用一个Service在后台进行时间倒计时,而我需要在多个Activity上同步显示该倒计时的信息。那么,Service上的倒计时功能即为被观察者(Observable),而这多个Activity则为观察者(Observer)。
Java自身带有Observable和Observer的接口,我们也可以自己自定义实现Observable和Observer,但是这就要求我们自己在Observable中维护Observer的列表。
首先,我们定义好观察者Observer的接口:
package com.vite.testobserver.observer.ifc; /** * 观察者接口 * * @author trs * */ public interface Observer { void update(Object data); }
然后定义被观察者Observable的接口:
package com.vite.testobserver.observer.ifc; /** * 被观察者接口 * * @author trs * */ public interface Observable { /** * 添加观察者 * * @param observer */ public void addObserver(Observer observer); /** * 删除观察者 * * @param observer */ public void deleteObserver(Observer observer); /** * 删除所有观察者 */ public void deleteObservers(); /** * 通知所有观察者 * * @param data */ public void notifyObservers(Object data); /** * 通知所有观察者 */ public void notifyObservers(); /** * 获取观察者数量 * * @return */ public int getCountObservers(); }
然后通过继承Observable的接口,自定义我们自己的被观察者类:
package com.vite.testobserver.observer; import java.util.ArrayList; import java.util.List; import com.vite.testobserver.observer.ifc.Observable; import com.vite.testobserver.observer.ifc.Observer; /** * 自定义被观察者 * * @author trs * */ public class TimeCountObservable implements Observable { private static List<Observer> observerList = new ArrayList<Observer>(); public static void GlobalAddObserver(Observer observer) { if (observerList == null) throw new NullPointerException(); if (observer == null) throw new NullPointerException(); synchronized (observerList) { if (!observerList.contains(observer)) observerList.add(observer); } } public static void GlobalDeleteObserver(Observer observer) { if (observerList == null) throw new NullPointerException(); if (observer == null) throw new NullPointerException(); synchronized (observerList) { if (observerList.contains(observer)) observerList.remove(observer); } } @Override public synchronized void addObserver(Observer observer) { // TODO Auto-generated method stub if (observerList == null) throw new NullPointerException(); if (observer == null) throw new NullPointerException(); synchronized (observerList) { if (!observerList.contains(observer)) observerList.add(observer); } } @Override public synchronized void deleteObserver(Observer observer) { // TODO Auto-generated method stub if (observerList == null) throw new NullPointerException(); if (observer == null) throw new NullPointerException(); synchronized (observerList) { if (observerList.contains(observer)) observerList.remove(observer); } } @Override public synchronized void deleteObservers() { // TODO Auto-generated method stub if (observerList == null) throw new NullPointerException(); synchronized (observerList) { observerList.removeAll(observerList); } } @Override public void notifyObservers(Object data) { // TODO Auto-generated method stub if (observerList == null) throw new NullPointerException(); synchronized (observerList) { for (Observer observer : observerList) { observer.update(data); } } } @Override public void notifyObservers() { // TODO Auto-generated method stub notifyObservers(null); } @Override public int getCountObservers() { // TODO Auto-generated method stub if (observerList == null) throw new NullPointerException(); synchronized (observerList) { return observerList.size(); } } }注意代码上面,记录观察者Observer的列表使用了static修饰,同时增加了两各静态方法GlobalAddObserver和GlobalDeleteObserver
这是为了在Service以外的地方动态添加和删除观察者,写得比较简单粗暴,在实际应用过程中我们也可以根据需求进行不同的自定义。
然后,通过对Activity实现观察者Observer接口中的updata方法,并将自身通过GlobalAddObserver加入到观察者列表中。
这样,在后台Service里的倒计时功能中调用notifyObservers方法,通知所有在观察者列表中的观察者,并将数据传递到updata方法中,就完成了一次数据更新。
private class TimeCountDownTimer extends CountDownTimer { public TimeCountDownTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); // TODO Auto-generated constructor stub } @Override public void onFinish() { // TODO Auto-generated method stub timeCountObservable.notifyObservers("00:00"); if (timer != null) timer.cancel(); timer = null; } @Override public void onTick(long millisUntilFinished) { // TODO Auto-generated method stub Date date = new Date(millisUntilFinished); timeCountObservable.notifyObservers(df.format(date)); } }
一般而言这样就可以了,但是偶尔会遇到一些情况,就是某个观察者的updata方法中耗时过长,这样会导致排在该观察者后面的其余观察者的无法及时更新数据。针对这个问题,我们可以用Handler来进行异步处理。
通过实现Observer接口,我们自定义一个可以异步处理的TimeCountObserver:
package com.vite.testobserver.observer; import android.os.Handler; import com.vite.testobserver.observer.ifc.Observer; public abstract class TimeCountObserver implements Observer { private Handler handler; private Object object; public TimeCountObserver(Handler handler) { this.handler = handler; } public abstract void onUpdate(Object data); @Override public void update(Object data) { // TODO Auto-generated method stub object = data; if (handler == null) onUpdate(object); else handler.post(new LocalRunnable()); } private class LocalRunnable implements Runnable { @Override public void run() { // TODO Auto-generated method stub onUpdate(object); } } }
然后在Activity中就无需实现Observer接口,而是实例化TimeCountObserver,并且通过onUpdate方法更新数据:
timeCountObserver = new TimeCountObserver(new Handler()) { @Override public void onUpdate(Object data) { // TODO Auto-generated method stub content.setText(data.toString()); } }; TimeCountObservable.GlobalAddObserver(timeCountObserver);
效果如下图所示:
该例子的下载地址如下:
http://download.csdn.net/detail/vite_s/9391248
相关文章推荐
- Android 4.0.4系统下实现apk的静默安装和启动
- Android自定义View 完整版
- Android+REST WebService服务方式手机开发
- Android中获取应用程序(包)的信息-----PackageManager的使用(一)
- android 5.0以下版本使用atof报错解决
- Android 传感器 I-传感器基本介绍
- Android瀑布流StaggeredGridView学习研究
- android 虚拟按键遮挡布局问题
- Android中AppWidget的分析与应用:AppWidgetProvider
- Android开发中无处不在的设计模式——单例模式
- Android_安装GooglePlay
- Android 系统快捷开关
- Android widget之PopupWindow
- 【框架学习】【android-Ultra-Pull-To-Refresh】
- Android开发常见问题
- Android 内存管理 &Memory Leak & OOM 分析
- android 利用一个TextView实现两行并且每行的字体大小和颜色各异
- 沉浸式状态栏
- AutoCompleteTextView使用
- android设置Activity背景色为透明的3种方