FileObserver不会对更改做出反应

时间:2011-06-19 18:41:55

标签: android

我遇到以下问题:

在我的Activity中,我有一个列表视图,列出了外部文件目录的内容。 我希望在内容发生任何类型的更改后立即更新列表,所以我有:

public class FileAdapter implements ListAdapter {
    private File mDirectory;
    private FileObserver mFileObserver;
    private DataSetObservable mDataSetObservable;

    public FileAdapter() {
    super();
    this.mDirectory =
        new ContextWrapper(ImportList.this).getExternalFilesDir(null);
        if (this.mDirectory != null) {
            this.mFileObserver = 
                new FileObserver(this.mDirectory.getAbsolutePath()) {
                    @Override
                    public void onEvent(int event, String path) {
                        new Handler().post(new Runnable() {
                            public void run() {
                                FileAdapter.this.mDataSetObservable.notifyChanged();
                            }
                        });
                    }
                };
        }
        this.mDataSetObservable = new DataSetObservable();
    }
    public void startWatching() {
        this.mFileObserver.startWatching();
    }

    public void stopWatching() {
        this.mFileObserver.stopWatching();
    }

    public boolean areAllItemsEnabled() {
        return true;
    }

    public boolean isEnabled(int position) {
        return true;
    }

    public int getCount() {
        return this.mDirectory == null ? 0 : this.mDirectory.listFiles().length;
    }

    public Object getItem(int arg0) {
        return this.mDirectory.listFiles()[arg0];
    }

    public long getItemId(int position) {
        return position;
    }

    public int getItemViewType(int position) {
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ItemView itemView;
        if (convertView == null) {
            itemView = new ItemView(ImportList.this, 1);
        } else {
            itemView = (ItemView) convertView;
        }
        File file = (File) this.getItem(position);
        itemView.setValue(0, file.getName());
        return itemView;
    }

    public int getViewTypeCount() {
        return 1;
    }

    public boolean hasStableIds() {
        return false;
    }

    public boolean isEmpty() {
        return this.getCount() < 1;
    }

    public void registerDataSetObserver(DataSetObserver observer) {
        this.mDataSetObservable.registerObserver(observer);
    }

    public void unregisterDataSetObserver(DataSetObserver observer) {
        this.mDataSetObservable.unregisterObserver(observer);
    }

    public String getPath() {
        return this.mDirectory == null ?
            ImportList.this.getResources().getString(R.string.no_external_files) :
            this.mDirectory.getAbsolutePath();
    }
}

作为我的活动的内部类

在我的onCreate中我做了:

this.mFileBrowser = (ListView) this.findViewById(R.id.listview_filebrowser);
....
this.mFileAdapter = new FileAdapter();
this.mFileBrowser.setAdapter(this.mFileAdapter);

在onResume()我做:

this.mFileAdapter.startWatching();

据我所知,例如,一旦从外部文件目录中删除文件,这应该会导致我的ListView自动重新加载。 但它不起作用!

2 个答案:

答案 0 :(得分:2)

另一件需要注意的事情是,不支持为同一路径创建多个FileObserver实例,这可能会导致某些竞争条件。因此,如果有可能为同一目录多次调用此代码,则可能会遇到问题。

答案 1 :(得分:0)

正如DJC所说,fileobserver不是递归的。如果你在google上进行了很好的搜索,你会发现一个非常好用的RecursiveFileObserver类。然而,我用它做的一件事就是使用startWatching方法,因为它需要永远设置,特别是对于复杂的目录树,因此我建议将其线程化为不绑定UI线程。