Introduction to FileObserver for Android file monitoring

Source: Internet
Author: User
Tags inotify

In the previous Linux File System Inotify mechanism, we introduced the Linux File Change monitoring process. The Android system encapsulates a FileObserver class to facilitate the use of the Inotify mechanism. FileObserver is an abstract class. You need to define a subclass to implement the onEvent abstract method of this class. When a file or directory change event is monitored, the onEvent () of FileObserver will be called back () function to process changes to files or directories.

Event monitoring process

The FileObserver class defines a static internal class named ObserverThread, which is used to monitor files or directories. All types of FileObserver have an ObserverThread instance:

Frameworks \ base \ core \ java \ android \ OS \ FileObserver. java

Public abstract class FileObserver {// event type that can be monitored public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE | CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE | DELETE_SELF | MOVE_SELF; // create and start a file monitoring thread in static mode: private static ObserverThread s_observerThread; static {s_observerThread = new ObserverThread (); s_observerThread.start ();} // instance private String m_path; private Integer m_descriptor; private int m_mask ;}

The FileObserver class constructs an ObserverThread object statically:

Public ObserverThread () {super ("FileObserver"); m_fd = init (); // Initialize an inotify instance. The Observer thread monitors this inotify instance}

Frameworks \ base \ core \ jni \ android_util_FileObserver.cpp

Static jint android_ OS _fileobserver_init (JNIEnv * env, jobject object) {# ifdef HAVE_INOTIFY return (jint) inotify_init (); // Initialize an inotify instance # else // HAVE_INOTIFY return-1; # endif // HAVE_INOTIFY}

Inotify_init () function implementation in Linux File System Inotify mechanism has a detailed introduction, and then start the ObserverThread, ObserverThread thread running body:

Frameworks \ base \ core \ java \ android \ OS \ FileObserve $ ObserverThread

Public void run () {observe (m_fd); // monitor inotify instance handle}

Frameworks \ base \ core \ jni \ android_util_FileObserver.cpp

Static void android_ OS _fileobserver_observe (JNIEnv * env, jobject object, jint fd) {# ifdef HAVE_INOTIFY char event_buf [512]; // defines the event array struct inotify_event * event; while (1) {int event_pos = 0; // read the event int num_bytes = read (fd, event_buf, sizeof (event_buf) from the inotify instance handle; if (num_bytes <(int) sizeof (* event) {if (errno = EINTR) continue; ALOGE ("***** ERROR! Android_ OS _fileobserver_observe () got a short event! "); Return;} // process the read events cyclically while (num_bytes >=( int) sizeof (* event) {int event_size; event = (struct inotify_event *) (event_buf + event_pos); jstring path = NULL; if (event-> len> 0) {path = env-> NewStringUTF (event-> name );} // call the onEvent function of ObserverThread to notify the upper layer of the response to env-> CallVoidMethod (object, method_onEvent, event-> wd, event-> mask, path ); if (env-> predictioncheck () {env-> predictiondescribe (); env-> Excep TionClear ();} if (path! = NULL) {env-> DeleteLocalRef (path);} event_size = sizeof (* event) + event-> len; num_bytes-= event_size; event_pos + = event_size ;}} # endif // HAVE_INOTIFY}

The ObserverThread cyclically reads the event from the inotify instance handle, and calls back the ObserverThread onEvent function to process the event.

Frameworks \ base \ core \ java \ android \ OS \ FileObserve $ ObserverThread

Public void onEvent (int wfd, int mask, String path) {// look up our observer, fixing up the map if necessary... fileObserver observer = null; synchronized (m_observers) {// find the registered FileObserver object WeakReference weak = m_observers.get (wfd) from the m_observers table based on the wfd handle; if (weak! = Null) {// can happen with lots of events from a dead wfdobserver = (FileObserver) weak. get (); if (observer = null) {m_observers.remove (wfd );}}}//... then call out to the observer without the sync lock heldif (observer! = Null) {try {// call the onEvent function of the corresponding FileObserver object to process the event observer. onEvent (mask, path);} catch (Throwable throwable) {Log. wtf (LOG_TAG, "Unhandled exception in FileObserver" + observer, throwable );}}}
Register monitoring watch

The FileObserver class provides the startWatching () function to start file monitoring.

Frameworks \ base \ core \ java \ android \ OS \ FileObserver. java

public void startWatching() {if (m_descriptor < 0) {m_descriptor = s_observerThread.startWatching(m_path, m_mask, this);}}

Monitoring started by the ObserverThread thread object

Frameworks \ base \ core \ java \ android \ OS \ FileObserver $ ObserverThread

Public int startWatching (String path, int mask, FileObserver observer) {// Add a watch object to the Inotify instance and obtain a watch object handle int wfd = startWatching (m_fd, path, mask); Integer I = new Integer (wfd); if (wfd> = 0) {// Save the watch object handle and FileObserver responding to the watch event as a key-value pair in the m_observers member variable synchronized (m_observers) {m_observers.put (I, new WeakReference (observer) ;}} return I ;}

ObserverThread calls the native method android_ OS _fileobserver_startWatching () to add a watch

Frameworks \ base \ core \ jni \ android_util_FileObserver.cpp

Static jint android_ OS _fileobserver_startWatching (JNIEnv * env, jobject object, jint fd, jstring pathString, jint mask) {int res =-1; # ifdef have_ino1_if (fd> = 0) {const char * path = env-> GetStringUTFChars (pathString, NULL); // Add a watch object res = inotify_add_watch (fd, path, mask) to the Inotify instance ); env-> ReleaseStringUTFChars (pathString, path) ;}# endif // HAVE_INOTIFY return res ;}
Log out of monitoring watch

The FileObserver class provides the stopWatching () function to stop file monitoring.
Frameworks \ base \ core \ java \ android \ OS \ FileObserver $ ObserverThread

public void stopWatching() {if (m_descriptor >= 0) {s_observerThread.stopWatching(m_descriptor);m_descriptor = -1;}}

Frameworks \ base \ core \ java \ android \ OS \ FileObserve $ ObserverThread

public void stopWatching(int descriptor) {stopWatching(m_fd, descriptor);}

Frameworks \ base \ core \ jni \ android_util_FileObserver.cpp

static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd){#ifdef HAVE_INOTIFY    inotify_rm_watch((int)fd, (uint32_t)wfd);#endif // HAVE_INOTIFY}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.