文档章节

Android源码设计模式解析与实战(十二)

_
 _OUTMAN_
发布于 2017/02/26 21:18
字数 465
阅读 4
收藏 0

1. 观察者模式定义

定义对象间一种一对多的依赖关系,使的每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新

2. 观察者模式的使用场景

(1) 关联行为场景,需要注意的是,关联行为是可拆分的,而不是"组合"关系。

(2) 事件多级触发场景。

(3) 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

3. Android源码分析

ListView最重要的一个功能就是Adapter,通常我们往ListView添加数据后,都会调用Adapter的notifyDataSetChanged()方法。

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
    // 数据采集观察者
    private final DataSetObservable mDataSetObservable = new DataSetObservable();
    ......
    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }
    /**
     * 当数据集变化时,通知所有观察者
     */
    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }
}
/**
 * 数据集观察者
 */
public class DataSetObservable extends Observable<DataSetObserver> {
    /**
     * 调用每个观察者的onChanged函数来通知它们被观察者发生了变化
     */
    public void notifyChanged() {
        // 调用所有观察者的onChanged方式
        for (int i = mObservers.size() - 1; i >= 0; i--) {
            mObservers.get(i).onChanged();
        }
    }
    ......
}

这些观察者就是ListView通过setAdapter方法设置产生的。

public void setAdapter(ListAdapter adapter) {
    // 如果已经有一个Adapter,那么先注销该Adapter对应的观察者
    if (mAdapter != null && mDataSetObserver != null) {
        mAdapter.unregisterDataSetObserver(mDataSetObserver);
    }
    ......
    super.setAdapter(adapter);
    if (mAdapter != null) {
        ......
        mDataSetObserver = new AdapterDataSetObserver();
        mAdapter.registerDataSetObserver(mDataSetObserver);
    } else {
        ......
    }
}

总结下,AdapterView中有一个内部类AdapterDataSetObserver,在ListView中设置Adapter时会构建一个AdapterDataSetObserver,并且注册到Adapter中。而Adapter中包含一个数据集看观察者DataSetObservable,在数据集发生变化时,开发者手动调用Adapter.notifyDataSetChanged,继而会遍历所有观察者的onChanged函数,然后调用ListView的requestLayout()重新布局,更新用户界面。

© 著作权归作者所有

共有 人打赏支持
_
粉丝 21
博文 133
码字总数 63959
作品 0
海淀
程序员
私信 提问
ListView 数据与UI更新机制之观察者模式

之前有一篇文章专门介绍观察者模式知识,当时通过EventBus来进行分析。近日在读《Android源码设计模式解析与实战》,看到书中介绍ListView中使用到观察者模式。为了加深对观察者模式的理解,...

Tifkingsly
07/13
0
0
Android 网络编程 目录

Android 网络编程 目录 Android 网络编程1 Http协议 Android 网络编程2 Okhttp缓存机制 Android 网络编程3 Java NIO to be continued... Android 架构师之路 目录 Android 架构师之路1 UML图...

香沙小熊
06/21
0
0
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
Android中的设计模式之工厂方法模式

参考 《设计模式:可复用面向对象软件的基础 》3.3 Factory method 对象创建型模式 《Android源码设计模式解析与实战》第5章 应用最广泛的模式--工厂方法模式 意图 定义一个用于创建对象的接...

newtrek
08/12
0
0
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho
04/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

MongoDB

MongoDB介绍 官网www.mongodb.com, 当前最新版3.4 C++编写,基于分布式的,属于NoSQL的一种 在NoSQL中是最像关系型数据库的 MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组...

chencheng-linux
19分钟前
1
0
Qt那些事0.0.10

release和debug在性能上差距很多,困扰我三周的问题很可能是因为这个。

Ev4n
34分钟前
4
0
flume1.8taildirSource

flume使用(一):入门demo flume使用(二):采集远程日志数据到MySql数据库 flume使用(三):实时log4j日志通过flume输出到MySql数据库 flume使用(四):taildirSource多文件监控实时采集...

hblt-j
35分钟前
1
0
redis--windows客户端引起的项目问题

一、redis安装 redis客户端下载地址:https://github.com/MSOpenTech/redis/releases。(redis一开始只支持Linux系统,后来有团队搞出了windows版,不过版本时间偏旧,也无所谓了,可以正常使...

随风飞临蛮荒境123
51分钟前
1
0
19《Java核心技术》之什么情况下Java程序会产生死锁?如何定位、修复?

一、提出问题 今天,我们会讨论一些日常开发中类似线程死锁等问题的排查经验,并选择一两修复过或者诊断过的核心类库死锁问题作为例子,希望不仅能在面试时,包括在日常工作中也能对你有所帮...

飞鱼说编程
52分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部