FileObserver doesn't react to changes
I am having the following problem:
In my Activity, I have a listview that lists the content of the external files directory. i want the list to be updated as soon as any kind of change occurs in the content, so I have:
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.m开发者_运维技巧Directory.getAbsolutePath();
}
}
as an inner class of my Activity
and in my onCreate I do:
this.mFileBrowser = (ListView) this.findViewById(R.id.listview_filebrowser);
....
this.mFileAdapter = new FileAdapter();
this.mFileBrowser.setAdapter(this.mFileAdapter);
And in onResume() I do:
this.mFileAdapter.startWatching();
So as I understand, this should cause my ListView to automatically reload as soon as a file is deleted from the external files directory, for example. But it doesn't work!
Another thing to be aware of is that creating more than one FileObserver instance for the same path is not supported and can lead to some race conditions. So if there is a chance that this code could get called more than once for the same directory you can run into problems.
As DJC said, the fileobserver is not recursive. If you do a good search on google, you'll find a RecursiveFileObserver Class that works very well. One thing I did with it, however, is thread the startWatching method because it takes forever to set up, especially with complex directory trees, so I would advise threading it as to not bind up the UI thread.
精彩评论