同一文件上的多个FileObserver失败

dar*_*ing 2 android android-file fileobserver

在我的应用程序中,我有不同的组件,它们使用FileObservers监视sdcard中的特定文件.因此,有两个文件观察器实例观察单个文件,例如所有事件的abc.xml.

FileObserver fo1 = new FileObserver(new File("/sdcard/abc.xml"));
fo1.startWatching();
FileObserver fo2 = new FileObserver(new File("/sdcard/abc.xml"));
fo2.startWatching();
Run Code Online (Sandbox Code Playgroud)

他们都注册了不同的活动.我的问题是当两个文件观察者并行观察时,我错过了对"fo1"的onEvent()的调用.

这是Android系统的限制吗?有什么方法可以解决这个问题?

Fim*_*ena 6

迟到但可能对其他人有帮助:这是Android中的一个错误 - 问题在这里报道.

因为这让我把头发撕掉了,所以我写了一个FileObserver的替代品,它通过维护FileObservers的主列表来解决这个问题.使用此FixedFileObserver替换应用程序中的所有FileObservers应导致预期的行为.(健康警告:我没有在所有角落情况下对它进行过广泛的测试,但它对我有用)

FixedFileObserver.java

package com.fimagena.filepicker.backend;

import android.os.FileObserver;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;


public abstract class FixedFileObserver {

    private final static HashMap<File, Set<FixedFileObserver>> sObserverLists = new HashMap<>();

    private FileObserver mObserver;
    private final File mRootPath;
    private final int mMask;

    public FixedFileObserver(String path) {this(path, FileObserver.ALL_EVENTS);}
    public FixedFileObserver(String path, int mask) {
        mRootPath = new File(path);
        mMask = mask;
    }

    public abstract void onEvent(int event, String path);

    public void startWatching() {
        synchronized (sObserverLists) {
            if (!sObserverLists.containsKey(mRootPath)) sObserverLists.put(mRootPath, new HashSet<FixedFileObserver>());

            final Set<FixedFileObserver> fixedObservers = sObserverLists.get(mRootPath);

            mObserver = fixedObservers.size() > 0 ? fixedObservers.iterator().next().mObserver : new FileObserver(mRootPath.getPath()) {
                @Override public void onEvent(int event, String path) {
                    for (FixedFileObserver fixedObserver : fixedObservers)
                        if ((event & fixedObserver.mMask) != 0) fixedObserver.onEvent(event, path);
                }};
            mObserver.startWatching();
            fixedObservers.add(this);
        }
    }

    public void stopWatching() {
        synchronized (sObserverLists) {
            Set<FixedFileObserver> fixedObservers = sObserverLists.get(mRootPath);
            if ((fixedObservers == null) || (mObserver == null)) return;

            fixedObservers.remove(this);
            if (fixedObservers.size() == 0) mObserver.stopWatching();

            mObserver = null;
        }
    }

    protected void finalize() {stopWatching();}
}
Run Code Online (Sandbox Code Playgroud)