FileObserver的应用以及原理

应用:
 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 监控的文件或者目录被移动,监控继续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值