Was working with FileObserver and ran into some serious limitations/design 
issues with it that are really not made clear in the documentation.

In my application among other reasons for needing to observe changes in the 
file system I have a file browser. When one is viewing a directory and then 
say switches to another app and makes a change to that directory, my app 
should react and reflect those changes so that you do not see stale data. 
So which paths are monitored are very dynamic and change as the user 
navigates my app.

The other design challenge is that I have different parts of the 
application that need to react to the file system changes and those 
different parts don't necessarily know about each other or care about the 
same FileObserver events.

So what I originally did was have those different parts each create their 
own FileObserver instance to monitor the events that each cares about. 
Turns out that having more than one FileObserver instance for the same path 
is not supported. The second FileObserver instance effectively replaces the 
first. There is nothing in the documentation about this, I only figured it 
out using grepcode.

Looking into it further there are some race conditions that can lead to 
indeterminate behavior if you ever create a new instance of FileObserver 
for the same path. Consider this:

    // Create an initial FileObserver
    observer = new FileObserver( myPath, someMask)
    {
        @Override public void onEvent(int event, 
String<http://developer.android.com/reference/java/lang/String.html>path)
        {
            Log.d(TAG,"In original observer");
        }
    };
    observer.startWatching;
...

    // Later replace it with a different FileObserver
    observer = new FileObserver(myPath, aDifferentMask)
    {
        @Override public void onEvent(int event, 
String<http://developer.android.com/reference/java/lang/String.html>path)
        {
            Log.d(TAG,"In new observer");
        }
    };
   observer.startWatching();

If a file system change occurs that falls within the mask, will the onEvent 
be called? The answer is that you can't tell for sure. It depends on the 
garbage collector. FileObserver has a finalizer that calls stopWatching. 
Because both instances internally refer to the same inotify watcher that 
means the new one will be stopped as well. So there are several 
possibilities:

   - The finalizer on the old instance gets called before your new instance 
   starts. You will get all your future events but there was a small window in 
   the transition where you could have missed events
   - The finalizer is called right after your new observer is started. You 
   will receive no file events on your new observer.
   - The finalizer is callled sometime in the future. You will get file 
   events for a while and then they will stop after the finalizer is called.

If you call stopWatching on the old instance before starting the new one 
you remove the indeterminacy, but you still have a window of time between 
the two where a file system change could occur and you will miss it.

Not sure what to do about it at this time. Looks like I will probably 
create a wrapper API for FileObserver that supports multiple listeners for 
the same path (with different event masks) and that internally only creates 
one FileObserver. Unfortunately, the only way I can see to make this work 
is to have the FileObserver instances themselves listen for all events and 
do the filtering myself because there is no good way around the race 
conditions of creating new FileObserver instances with different masks.

So the bottom line is that creating more than one FileObserver instance for 
the same path is not supported. So if you create a FileObserver instance 
for a path that needs to be the only instance until you call stopWatching 
on it.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to