FileObserver递归监听目录(解决无法监听目录的创建、删除问题)

来源:互联网 发布:超市叫卖软件 编辑:程序博客网 时间:2024/05/21 09:43

  • FileObserver递归监听目录解决无法监听目录的创建删除问题
    • 主要内容
    • 总结

FileObserver递归监听目录(解决无法监听目录的创建、删除问题)

主要内容

为了解决Android媒体数据库更新不及时的问题,我想打算通过FileObserver监听SD卡根目录下所有文件的变化,然后根据文件的变化对Android媒体数据库进行更新。而FileObserver无法做到递归监听。通过参考FileObserver 研究及其递归监听初步实现这篇博客,在其基础上,主要解决了几个问题:

  1. 无法监听目录的创建、删除
  2. 开启监听之后,新创建的目录无法监听
  3. 冗余注册监听的问题

冗余注册监听我是通过用ArrayMap键值对来解决的,以监听目录的绝对路径作为key,以监听器作为value。(也可以使用ArraySet集合实现)而开启监听之后,新创建的目录无法监听的问题则是通过监听FileObserver.CREATE事件,当创建新目录且该目录还没注册监听时,就注册并启动监听。
接下来,干货来了,代码如下:

public class RecursiveFileObserver extends FileObserver{    Map<String, SingleFileObserver> mObservers;    String mPath;    int mMask;    public RecursiveFileObserver(String path)    {        this(path, ALL_EVENTS);    }    public RecursiveFileObserver(String path, int mask)    {        super(path, mask);        mPath = path;        mMask = mask;    }    @Override public void startWatching()    {        if (mObservers != null)            return ;        mObservers = new ArrayMap<>();        Stack stack = new Stack();        stack.push(mPath);        while (!stack.isEmpty())        {            String temp = (String) stack.pop();            mObservers.put(temp, new SingleFileObserver(temp, mMask));            File path = new File(temp);            File[] files = path.listFiles();            if (null == files)                continue;            for (File f: files)            {                // 递归监听目录                if (f.isDirectory() && !f.getName().equals(".") && !f.getName()                        .equals(".."))                {                    stack.push(f.getAbsolutePath());                }            }        }        Iterator<String> iterator = mObservers.keySet().iterator();        while (iterator.hasNext()) {            String key = iterator.next();            mObservers.get(key).startWatching();        }    }    @Override public void stopWatching()    {        if (mObservers == null)            return ;        Iterator<String> iterator = mObservers.keySet().iterator();        while (iterator.hasNext()) {            String key = iterator.next();            mObservers.get(key).stopWatching();        }        mObservers.clear();        mObservers = null;    }    @Override public void onEvent(int event, String path)    {        int el = event & FileObserver.ALL_EVENTS;        switch (el)        {            case FileObserver.ATTRIB:                Log.i("RecursiveFileObserver", "ATTRIB: " + path);                break;            case FileObserver.CREATE:                File file = new File(path);                if(file.isDirectory()) {                    Stack stack = new Stack();                    stack.push(path);                    while (!stack.isEmpty())                    {                        String temp = (String) stack.pop();                        if(mObservers.containsKey(temp)) {                            continue;                        } else {                            SingleFileObserver sfo = new SingleFileObserver(temp, mMask);                            sfo.startWatching();                            mObservers.put(temp, sfo);                        }                        File tempPath = new File(temp);                        File[] files = tempPath.listFiles();                        if (null == files)                            continue;                        for (File f: files)                        {                            // 递归监听目录                            if (f.isDirectory() && !f.getName().equals(".") && !f.getName()                                    .equals(".."))                            {                                stack.push(f.getAbsolutePath());                            }                        }                    }                }                Log.i("RecursiveFileObserver", "CREATE: " + path);                break;            case FileObserver.DELETE:                Log.i("RecursiveFileObserver", "DELETE: " + path);                break;            case FileObserver.DELETE_SELF:                Log.i("RecursiveFileObserver", "DELETE_SELF: " + path);                break;            case FileObserver.MODIFY:                Log.i("RecursiveFileObserver", "MODIFY: " + path);                break;            case FileObserver.MOVE_SELF:                Log.i("RecursiveFileObserver", "MOVE_SELF: " + path);                break;            case FileObserver.MOVED_FROM:                Log.i("RecursiveFileObserver", "MOVED_FROM: " + path);                break;            case FileObserver.MOVED_TO:                Log.i("RecursiveFileObserver", "MOVED_TO: " + path);                break;        }    }    class SingleFileObserver extends FileObserver    {        String mPath;        public SingleFileObserver(String path) {            this(path, ALL_EVENTS);            mPath = path;        }        public SingleFileObserver(String path, int mask)        {            super(path, mask);            mPath = path;        }        @Override public void onEvent(int event, String path)        {            if(path != null) {                String newPath = mPath + "/" + path;                RecursiveFileObserver.this.onEvent(event, newPath);            }        }    }}

总结

这算是一个比较好的递归监听解决方案,当然还可以进行优化,比如监听目录的删除事件,并取消该目录的监听。最后,吐槽一下,博客就是个人感想和收获的总结,到处抄来抄去没什么意思。看完别人的博客之后,我们应该写出自己的见解,提出更好的解决方案,而不是收藏、转载和抄袭。最后,借鉴别人的东西,请注明出处。

0 0
原创粉丝点击