Android源码学习之观察者模式应用及优点介绍

2016-02-19 10:55 1 1 收藏

生活已是百般艰难,为何不努力一点。下面图老师就给大家分享Android源码学习之观察者模式应用及优点介绍,希望可以让热爱学习的朋友们体会到设计的小小的乐趣。

【 tulaoshi.com - 编程语言 】

观察者模式定义
Define a one-to-many dependency between objects so that when one object changes state, all its dependents aer notified and updated automatically.
定义对象间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
 
如上图所示(截取自《Head First Design Patterns》一书),主要包括四个部分
1. Subject被观察者。是一个接口或者是抽象类,定义被观察者必须实现的职责,它必须能偶动态地增加、取消观察者,管理观察者并通知观察者。
2. Observer观察者。观察者接收到消息后,即进行update更新操作,对接收到的信息进行处理。
3. ConcreteSubject具体的被观察者。定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
4. ConcreteObserver具体观察者。每个观察者在接收到信息后处理的方式不同,各个观察者有自己的处理逻辑。
观察者模式有什么优点呢
观察者和被观察者之间是抽象耦合的,不管是增加观察者还是被观察者都非常容易扩展。
根据单一职责原则,每个类的职责是单一的,那么怎么把各个单一的职责串联成真实的复杂的逻辑关系呢,观察者模式可以起到桥梁作用。
观察者模式是松耦合的典型。
在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.

来源:https://www.tulaoshi.com/n/20160219/1596093.html

延伸阅读
本文主要讲解Android应用程序签名相关的理论知识,包括:什么是签名、为什么要给应用程序签名、如何给应用程序签名等 。 1、什么是签名?       如果这个问题不是放在Android开发中来问,如果是放在一个普通的版块,我想大家都知道签名的含义。可往往就是将一些生活中常用的术语放在计算机这种专业领域,大家就开...
为了引入这个概率 首先从需求说起 即:现有某Activity专门用于手机属性设置 那么应该如何做呢? 根据已学知识 很快一个念头闪过 即:Activity + Preference 组合 前者用于界面构建 后者用于设置数据存放 其实 这是正确的 但是 这会比较繁琐 因为 每个设置选项 都要建立与其对应的Preference 所以 现在有更好的选择了 那就是本文的主角:Prefer...
标签: 网络游戏
《大冲锋》战术之占领模式战术及应用 攻略导航 刀战攻略 占领据点攻略 BOSS战专题 大冲锋 是一款不错的休闲类FPS 游戏 ,但是作为一名菜鸟,我们经常不知不觉就输了战斗,都怪我们平常只顾着杀人却忽略了游戏模式的关键点!那么今天这里,图老师图老师小编我来给大家分析分析据点战(占领模式)中的一些要素,...
1.MapView ,MapActivity 这种的局限在于,必须要继承MapActivity,否则无法使用MapView。纠结就在于此。但是,最新官网上已经弃用了这糟粕的MapActivity。 Version 1 of the Google Maps Android API as been officially deprecated as of December 3rd, 2012. This means that from March 3rd, 2013 you will no longer be able to request a...
看到很多书中都没有对PreferenceActivity做介绍,而我正好又在项目中用到,所以就把自己的使用的在这总结一下,也方便日后查找。 PerferenceActivity是什么,看下面的截图:               Android系统截图(左)MusicPlayer Setting截图(右) 好了,我们看到Android系统本...

经验教程

289

收藏

83
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部