Android 观察者模式

原创 2016年05月31日 23:26:05

观察者模式,是一种非常常见的设计模式,在很多系统中随处可见,尤其是涉及到数据状态发生变化需要通知的情况下。
本文以AbstractCursor为例子,展开分析。
观察者模式,Observer Pattern,是一个很实用的模式,本人曾经接触到的各种平台以及曾经参与项目中打印模板解释器中都用到了此模式。

1.意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
热门词汇:依赖 发布-订阅 事件 通知 更新 监听 



观察者模式:观察者和被观察者


1.观察者接收到消息后,即进行update更新操作,对接收到的信息进行处理。

   一个类如果实现观察者的接口,则只需要实现一个update()方法,注意还需要在此类中添加一个被观察者(主题(被观察者)的实例.addObserver(this);)this指实现了观察者接口的对象

观察者模式有什么优点呢
观察者和被观察者之间是抽象耦合的,不管是增加观察者还是被观察者都非常容易扩展。
根据单一职责原则,每个类的职责是单一的,那么怎么把各个单一的职责串联成真实的复杂的逻辑关系呢,观察者模式可以起到桥梁作用。
观察者模式是松耦合的典型。 简单的代码如下:

  public class ObserverObj extends Activity implements Observer{

     private ObservableObj observableObjChange; 

       @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_service);
cx = this;

                // 在哪个类中使用观察者时必须把实现了该接口的观察者(订阅者)添加到被观察者(发布者)中,方便发布者发布信息时通过notify方法时能被观察者接收到变化的数据。

ObservableObj .getObservableObj ().addObserver(this);

         }


     @Override
public void update(Observable observable, Object data) {
observableObjChange = (ObservableObj ) observable;
List<Tree> list = observableObjChange.getList();
Message message = Message.obtain();
message.what = 1;
message.obj = list;

               // 交由主线程去更新ui控件
handler.sendMessage(message);

}


 }



2. 被观察者(发布者)是一个接口或者是抽象类,定义被观察者必须实现的职责,它必须能偶动态地增加、取消观察者(订阅者),管理观察者并通知观察者(android自带的被观察者已经封装好添加、取消、移除观察者对象)。

   一个类实现被观察者的接口,

  public class ObservableObj extends Observable {

          public static ObservableObj observableObj;

          public static ObservableObj getObservableObj () {
   if (observableObj== null) {
  observableObj= new ObservableObj ();
   }
   return observableObj;
   }


        //被观察者中数据源发生变化后执行以下代码

setChanged();
//之后去执行ObserverObj 中重写的update()
notifyObservers();
       


 }


注:使用android自带的观察者模式的话,实现被观察者接口的类中当数据源发生变化时候,只需要执行通知观察者就可以

       setChanged();
//之后去执行ObserverObj 中重写的update()
notifyObservers();

        之后观察者那边执行update()方法

如果不适用Android自带的观察者的话,只需要在声明的被观察者的接口中声明添加、取消、移除、通知(notifyObservers)观察者对象的方法

                                                                      在声明的观察者的接口中声明更新的方法即可


在Android源码中,其中一个经典的使用到观察者模式的就是Android控件的事件监听模型。 
一、下面简要说明Android交互事件传输的设计原理和特征: 
交互事件,是指当用户通过按键、触摸、滑动等操作与应用进行交互时触发的相关事件。通过Android控件树可知,交互事件是沿着控件树自顶向下传播的。其中Android控件树简要图如下所示: 


 
当位于控件树上层的父控件收到交互事件后,会先行判定该事件的目标控件对象,如果该事件正是自己所需要的,则会截获事件进行处理,否则就尝试将事件向下分发给对应的子控件,并对推的逐级向下传播事件,直至该事件被处理或者忽略。 

Android在View类中定义了一系列命名为View.On***的事件函数用来接收和处理各类交互事件,如通过View.OnKeyDown函数可以接收到用户的按键操作等。每个派生自View类的子控件都可以通过重载这些事件函数,来处理该控件所需的事件。 

例如,如果一个控件需要处理用户按返回键的操作,则可以通过重载View.onKeyDown函数来实现: 
复制代码代码如下:

/* 
* @see android.app.Activity#onKeyDown(int, android.view.KeyEvent) 
*/ 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
// 监听和处理返回操作 
if(keyCode == KeyEvent.KEYCODE_BACK) { 
doSomething(); 
return true; 

return false; 


事件函数的返回值是控制事件传播的重要手段。如果事件函数返回true,则说明该控件已经接收并完成了该事件的处理,无须将该事件进一步传递;反之,如果事件函数返回false,则说明该控件对象未能处理该事件(或虽然做过处理,但仍需要进一步处理),需要继续传递以寻找能够处理它的控件对象。 

对于容器控件ViewGroup来说,它的一个职责就是将交互事件传播到其子控件中。针对不同的事件,ViewGroup可以选择不同的传播方式。如,如果是触摸事件,ViewGroup对象需要判定该事件发生的区域位于哪个子控件上,从而将该事件分配给该子控件进行处理。但通过继承的方式来进行事件处理并不够灵活,会导致系统中出现大量的子控件类型,并且各个控件的复用性都较差。因此采用“组合”来代替“继承”。基于此思想,View类中提供了一系列配套的事件监听函数供开发者处理对应事件,这就有了使用观察者模式来完成Android控件的事件监听模型。开发者可以构造外部观察者对象与控件对象的事件监听接口绑定,获取事件消息。 
还是以上面的按键事件为例,通过监听者进行处理的实现如下所示: 
复制代码代码如下:

final View.OnKeyListener listener = new OnKeyListener() { 
@Override 
public boolean onKey(View v, int keyCode, KeyEvent event) { 
// 处理返回键事件 
if(keyCode == KeyEvent.KEYCODE_BACK) { 
doSomething(); 
return true; 

return false; 

}; 
。。。 
mUISetButton = (Button) findViewById(R.id.setValue); 
// 将按钮与监听对象绑定 
mUISetButton.setOnKeyListener(listener); 

通过利用外部对象来处理交互事件,其耦合性低,使每个类控件都具有更好的可复用度,无须为了处理事件而构造新的控件。 
二、现在开始看看源代码是怎么进行组织使用“观察者模式”的 
1. 看View类源代码中的OnKeyListener接口: 
复制代码代码如下:

/** 
* Interface definition for a callback to be invoked when a key event is 
* dispatched to this view. The callback will be invoked before the key 
* event is given to the view. 
*/ 
public interface OnKeyListener { 
/** 
* Called when a key is dispatched to a view. This allows listeners to 
* get a chance to respond before the target view. 

* @param v The view the key has been dispatched to. 
* @param keyCode The code for the physical key that was pressed 
* @param event The KeyEvent object containing full information about 
* the event. 
* @return True if the listener has consumed the event, false otherwise. 
*/ 
boolean onKey(View v, int keyCode, KeyEvent event); 


2. 再看View类定义了私有成员mOnKeyListener(通过组合的方式): 
private OnKeyListener mOnKeyListener; 
3. 注册listener 
复制代码代码如下:

/** 
* Register a callback to be invoked when a key is pressed in this view. 
* @param l the key listener to attach to this view 
*/ 
public void setOnKeyListener(OnKeyListener l) { 
mOnKeyListener = l; 


4. 剩下的就交给开发者自己构造外部观察者对象与该按键的事件接口进行绑定,获取事件消息。 
最后让我们记住支撑“观察者模式”的设计原则: Strive for loosely coupled designs between objects that interact. 


详情可参考:http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html


Android设计模式学习之观察者模式

观察者模式在实际项目中使用的也是非常频繁的,它最常用的地方是GUI系统、订阅——发布系统等。因为这个模式的一个重要作用就是解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。以GUI系统来说,应用的UI...
  • u012124438
  • u012124438
  • 2017年02月17日 00:25
  • 9816

Android设计模式(十一)-观察者模式

观察者模式是一种使用频率非常高的设计模式,最常用的地方就是订阅-发布系统。这个模式的重要作用就是将观察者和被观察者解耦,使他们之间的依赖更小甚至没有。定义定义对象一种一对多的依赖关系,使得每当一个对象...
  • qq_25806863
  • qq_25806863
  • 2017年04月05日 00:26
  • 565

Android开发中无处不在的设计模式——观察者模式

ndroid开发中无处不在的设计模式——单例模式 Android开发中无处不在的设计模式——Builder模式 前面介绍了单例模式和Builder模式,有兴趣的见上面两个链接,这篇文章着重介绍一下观察...
  • sbsujjbcy
  • sbsujjbcy
  • 2015年10月20日 21:55
  • 4721

android实现观察者模式的几种方法

观察者模式在 android开发中应用还是非常广泛的,例如android按钮事件的监听、广播等等,在任何类似于新闻-订阅的模式下面都可以使用。从某种意义上面来说android有点像JAVA EE的WE...
  • dsc114
  • dsc114
  • 2016年08月03日 16:14
  • 2306

Android中的观察者模式简单使用

观察者模式 “定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都将得到通知,并自动更新”,可以理解成多个观察者向一个被观察者订阅消息,当被观察者发生改变时通知相应的...
  • u011326979
  • u011326979
  • 2016年03月02日 11:30
  • 851

Android设计模式之观察者模式(Observer Pattern)

观察者模式介绍观察者模式是一个使用率非常高的模式,它最常用的地方就是GUI系统、订阅–发布系统。因为这个模式的一个重要作用就是解耦,将观察者和被观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。...
  • happy_horse
  • happy_horse
  • 2016年05月30日 21:05
  • 1778

Android 中的观察者模式Observer

Android 中的观察者模式 实现的简单框架。
  • feidu804677682
  • feidu804677682
  • 2014年12月26日 09:51
  • 10164

[Android开发] RxJava2之路一 - 观察者模式

一、 简介是本人学习RxJava的经验总结,因为RxJava是基于这个模式的,所以我们先学习这个观察者模式,是完全必要的。会了这个模式再看RxJava就简单很多了。二、啥是观察者模式?观察者模式(Ob...
  • niubitianping
  • niubitianping
  • 2017年02月07日 19:10
  • 1226

回调函数和观察者模式

Android的框架中有非常多的地方使用了回调的模式,例如Activity的生命周期,按钮的点击事件等。 下面是回调的基本模型: [java] view plain...
  • yxwbtb
  • yxwbtb
  • 2015年07月15日 17:13
  • 2891

"观察者模式"-之Java,Android面试必问设计模式(8/9)

1.实现了通观察者接口的多个观察者 2.管理接口,定义操作方法 3.管理"抽象类"-实现-"管理接口",但只重写详细的操作方法:增加,删除,通知 4.管理的"具体类"-**继承**抽象类,重写一...
  • nzfxx
  • nzfxx
  • 2016年06月28日 15:48
  • 933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 观察者模式
举报原因:
原因补充:

(最多只允许输入30个字)