FileObserver-android项目——观察者模式应用分析
项目的GitHub来源:https://github.com/doyee/FileObserver-android/blob/master/FileObserver/src/custom/fileobserver/FileObserver.java
https://github.com/doyee/FileObserver-android/blob/master/FileObserver/src/custom/fileobserver/FileWatcher.java
1、概述
观察者模式是一种对象的行为模式,也叫做发布-订阅模式、源-监听器模式或从属者模式。观察者模式可以让多个观察者同时监听某一个主题对象,从而形成一对多的依赖关系,当主题对象状态发生变化的时候,就会通知所有观察者对象,使它们能够自动更新。理想的观察者模式使用还应避免或者降低对象之间的耦合。
1)抽象主题:抽象主题负责将所有的观察者对象引用保存到一个聚集里,每个主题都可以有相当数量的观察者。在抽象主题中会提供一个接口,来增加和删除观察者对象。
2)具体主题:具体主题就是用来把相关的状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3)抽象观察者:抽象观察者负责给所有的具体观察者定义一个接口,在得到主题通知时更新自己。
4)具体观察者:具体的观察者就是实现抽象观察者角色所要求的更新接口,以此来使自己的状态和主题状态相一致。
2、观察者主题抽象对象:
public abstract class FileObserver {
/** Event type: Data was read from a file */
public static final int ACCESS = 0x00000001;
/** Event type: Data was written to a file */
public static final int MODIFY = 0x00000002;
/** Event type: Metadata (permissions, owner, timestamp) was changed explicitly */
public static final int ATTRIB = 0x00000004;
/** Event type: Someone had a file or directory open for writing, and closed it */
public static final int CLOSE_WRITE = 0x00000008;
/** Event type: Someone had a file or directory open read-only, and closed it */
public static final int CLOSE_NOWRITE = 0x00000010;
/** Event type: A file or directory was opened */
public static final int OPEN = 0x00000020;
/** Event type: A file or subdirectory was moved from the monitored directory */
public static final int MOVED_FROM = 0x00000040;
/** Event type: A file or subdirectory was moved to the monitored directory */
public static final int MOVED_TO = 0x00000080;
/** Event type: A new file or subdirectory was created under the monitored directory */
public static final int CREATE = 0x00000100;
/** Event type: A file was deleted from the monitored directory */
public static final int DELETE = 0x00000200;
/** Event type: The monitored file or directory was deleted; monitoring effectively stops */
public static final int DELETE_SELF = 0x00000400;
/** Event type: The monitored file or directory was moved; monitoring continues */
public static final int MOVE_SELF = 0x00000800;
public static final int UNMOUNT = 0x00002000;
public static final int Q_OVERFLOW = 0x00004000;
public static final int IGNORED = 0x00008000;
public static final int CLOSE = (CLOSE_WRITE | CLOSE_NOWRITE);
public static final int MOVE = (MOVED_FROM | MOVED_TO);
public static final int ONLYDIR = 0x01000000;
public static final int DONT_FOLLOW = 0x02000000;
public static final int MASK_ADD = 0x20000000;
public static final int ISDIR = 0x40000000 ;
public static final int ONESHOT = 0x80000000;
/** Event mask: All valid event types, combined */
public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE
| CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE
| DELETE_SELF | MOVE_SELF;
public static int FILE_CHANGED = CREATE | DELETE | MOVED_FROM | MOVED_TO | CLOSE_WRITE;/* MODIFY | ATTRIB*/;
private static final String LOG_TAG = "FileObserver";
private static class FolderFilter implements FileFilter{... }
private static class ObserverThread extends Thread {...}
......
}
这个FileObserver是一个抽象类,这里简略打出,详细代码见GitHub链接源代码,这个FileObserver类中首先定义了一系列常量数据结构,用来区分各种不同的文件及目录的事件状态,例如有:1)数据在一个文件中已被打开状态;
2)数据在一个文件中被写入状态;
3) 元数据被修改;
4) 某人对一个文件或目录有打开写入并关闭的权限;
5) 某人对一个目录或文件只读权限;
6) 一个文件或目录已经被打开状态;
7) 一个文件或子目录从一个监听目录转移;
8) 一个新文件或子目录已经在监听目录上创建了;
9) 一个文件已经在监听目录上被删除了;
10) 监听文件或目录已经被删除;
11) 有效监听停止了
12) 监听文件或目录已被转移,监听正在继续;
等等...
接着在抽象主题中定义了一个过滤器——FolderFilter,这个类继承自FileFilter,用来过滤所输入的路径是否为一个目录。最后,抽象主题中还定义了一个线程类,其中用HashMap定义了一个观察者集合和路径集合,利用同步块锁的方式,定义了开始和停止函数。
3、具体观察者实现
public class FileWatcher extends FileObserver {
FileListener mFileListener;
Hashtable<Integer, String> mRenameCookies = new Hashtable<Integer, String>();
public FileWatcher(String path) {
this(path, ALL_EVENTS);
}
public FileWatcher(String path, int mask) {
this(path, false,mask);
}
public FileWatcher(String path, boolean watchsubdir,int mask) {
super(path, watchsubdir,mask);
}
public void setFileListener(FileListener fl){
mFileListener = fl;
}
@Override
public void onEvent(int event,int cookie,String path) {
switch (event) {
......
}
}
FileWatcher类继承自之前定义的FileObserver抽象类,包括FileWatcher()函数、setFileListener()函数和onEvent()函数都根据需要进行了重写,根据抽象主题的变化来更新自己。从而实现把给定路径上的文件或目录的状态以此写入日志。
4、结构图示:

只有订阅了文件观测的抽象类,就有了新的文件类型控制,就会发送到订阅者那里,当不想订阅该服务的时候,取消继承也就是不会再接收该服务了。可见,观察者模式有不少的优点:(1)其可以在观察者和被观察者之间建立一个抽象的耦合,被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口;(2)观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知.
由此项目中,不同的FileWatcher观察者可独立运行一个线程,多个观察者共同进行,从而完成不同的共性工作,这点对于比较统一的工作性质有作用,能显著提升效率。

浙公网安备 33010602011771号