Android File Monitoring Fileobserver Introduction

Source: Internet
Author: User

The Linux file change monitoring process is described in the previous Linux filesystem inotify mechanism . On this basis, the Android system encapsulates a fileobserver class to facilitate the use of the inotify mechanism. Fileobserver is an abstract class that needs to define a subclass's OnEvent abstract method that implements the class, and when the monitored file or directory changes events, it calls back Fileobserver's onevent () function to handle the file or directory change events.

Event Monitoring Process

A static inner class observerthread is defined in the Fileobserver class, which is the real implementation of the file or directory monitoring process. All types of fileobserver have a Observerthread instance:

Frameworks\base\core\java\android\os\fileobserver.java

Public abstract class Fileobserver {    //monitored event type public static final int all_events = ACCESS | MODIFY | ATTRIB | Close_write            | Close_nowrite | OPEN | Moved_from | moved_to | DELETE | CREATE | delete_self | move_self;//statically creates and starts a file monitoring thread 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 a Observerthread object statically:

Public Observerthread () {Super ("Fileobserver"); m_fd = init ();//Initializes a inotify instance, and the observer thread is the one that monitors the 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 a INOTIFY instance   #else//have_inotify    return-1; #endif//Have_inotify}

The Inotify_init () function implementation is described in detail in the Linux file system inotify mechanism , and then the Observerthread thread is started, and the observerthread thread runs the 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[51    2];//defining event arrays struct inotify_event* event;         while (1) {int event_pos = 0;//reads an event from the inotify instance handle int num_bytes = Read (fd, event_buf, sizeof (EVENT_BUF));            if (Num_bytes < (int) sizeof (*event)) {if (errno = = eintr) continue; Aloge ("* * * * error!            Android_os_fileobserver_observe () got a short event! ");        Return            }//Loop handles the read-to event 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); }//calls Observerthread's OnEvent function to notify the upper response Env->callvoidmethod (object, Method_onevent, EVENT-&GT;WD, Event->mask            , path); if (env->excEptioncheck ()) {env->exceptiondescribe ();            Env->exceptionclear ();            } 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 thread loop reads the event from the INotify instance handle and then callbacks the Observerthread onevent function to handle the event.

Frameworks\base\core\java\android\os\fileobserve$observerthread

public void onEvent (int wfd, int. mask, String Path) {//Look up to our observer, fixing up the map if necessary ... Fileobserver observer = null;synchronized (m_observers) {//Based on WFD handle find registered M_observers object from Fileobserver table WeakReference weak = M_observers.get (WFD), if (weak! = null) {  //can happen with lots of events from a dead Wfdobserver = (fileobser ver) weak.get (); if (Observer = = null) {m_observers.remove (WFD);}}} Observer without the sync Lock HELDIF (Observer! = NULL) {try {//Call the Fileobserver function of the corresponding OnEvent object to Handle Event Observer.onevent (mask, path);} catch (Throwable throwable) {log.wtf (Log_tag, "Unhandled exception in Fileobserver" + Observer, Throwable);}}}
Registration Monitoring Watch

The Fileobserver class provides the startwatching () function to initiate 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 );}}

Start monitoring by 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 get a watch object handle int wfd = StartWatching (m_fd, path, mask); Integer i = new Integer (WFD); if (wfd >= 0) {// Saves the Watch object handle and the Fileobserver in response 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 also 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_inotify    if (fd >= 0)    {        const char* path = Env->getstringutfchars (pathstring , NULL);//Add a Watch object to the INotify instance        res = Inotify_add_watch (fd, path, mask);        Env->releasestringutfchars (pathstring, path);    } #endif//Have_inotify    return res;}
Logout Monitor Watch

The Fileobserver class provides the use of 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}

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.