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