应用:
int flags = FileObserver.CREATE | FileObserver.MOVED_TO;
mObserver = new FileObserver(REPORT_DIR.getPath(), flags) {
public void onEvent(int event, String path) {//事件触发
mHandler.post(new Runnable() { public void run() { scanDirectory(); } });
}
jni层调用ObserverThread的onEvent函数通知上层响应
public void onEvent(int wfd, int mask, String path) {
// look up our observer, fixing up the map if necessary...
FileObserver observer = null;
synchronized (m_observers) {
//根据wfd句柄从m_observers表中查找出注册的FileObserver对象
WeakReference weak = m_observers.get(wfd);
if (weak != null) { // can happen with lots of events from a dead wfd
observer = (FileObserver) weak.get();
if (observer == null) {
m_observers.remove(wfd);
}
}
}
// ...then call out to the observer without the sync lock held
if (observer != null) {
try {
//调用对应的FileObserver对象的onEvent函数来处理事件
observer.onEvent(mask, path);
} catch (Throwable throwable) {
Log.wtf(LOG_TAG, "Unhandled exception in FileObserver " + observer, throwable);
}
}
}
env->CallVoidMethod(object, method_onEvent, event->wd, event->mask, path);
可以继承FileObserver实现自定义的MyFileObserver,目的是监控onEvent回调,然后执行startWatching启动监控,在需要停止监控的时候执行stopWatching
@Override
public void onStart() {
super.onStart();
mObserver.startWatching();
scanDirectory();
}
@Override
public void onStop() {
super.onStop();
mObserver.stopWatching();
}
如果在开发的过程中,遇到onEvent无法接收的问题,先确认对以下几种可能原因进行排除。
FileObserver对象实例被回收 (思路:通过放在Application中进行测试)
初始化顺序问题 (思路:尽早的对FileObserver进行初始化)
没有读写文件权限问题 (思路: 文件监控需要文件读写权限)
onEvent中做复杂操作 (思路: 先跑通,再实现逻辑)
妨碍 inotify的可能性
同一个进程中,如果有两个不同的FileObserver同时监控一个Path,只有后调用startWatching的FileObserver能够收到onEvent回调。(Android系统Bug)
FileObserver 使用过程的大坑 就是权限!两种权限,一种是SD卡的读写权限,一种是android 系统使用这个API的权限
另外,如果想在系统休眠的时候,创建文件和文件夹,需要修改 SE权限,这部分在system/sepolicy ,然后编译boot.img
public int startWatching(String path, int mask, FileObserver observer) {
int wfd = startWatching(m_fd, path, mask);
Integer i = new Integer(wfd);
if (wfd >= 0) {
synchronized (m_observers) {
m_observers.put(i, new WeakReference(observer));
}
}
return i;
}
其中有m_observers对象锁,所有在我们调用MyFileObserver的 startWatching时,尽量不要放在自己实现的对象锁中实现,可能会引发死锁操作,从而导致ANR。
1 ACCESS 从文件中读取数据
2 MODIFY 从文件中编辑数据
4 ATTRIB 文件元数据(权限,拥有者,时间戳)被明确改变
8 CLOSE_WRITE 有人打开文件或者目录进行书写,并且关闭它
16 CLOSE_NOWEITTE 有人打开文件或者目录没有编辑,并且关闭它
32 OPEN 一个文件或者目录被打开
64 MOVE_FROM 一个文件或者子目录从被监控目录被移出
128 MOVE_TO 一个文件或者子目录被移入到被监控的目录
256 CREATE 一个文件或者子目录在被监控的目录下被创建
512 DELETE 文件从监控目录被删除
1024 DELETE_SELF 监控的文件或者目录被删除,监控停止
2048 MOVE_SELF 监控的文件或者目录被移动,监控继续