关闭

PackageManagerService中运用inotify去监控目录中的APK更新、安装和删除

219人阅读 评论(0) 收藏 举报
分类:

这是linux下inotify的一个demo程序,inotify 是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知, 這裏主要去监控/work/test目录下的文件增加、删除事件

 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <sys/mman.h>
 5 #include <stdio.h>
 6 #include <sys/inotify.h>

 8 #define BUF_LEN 1024
 9 #define PATH "/work/test"
 10 
 11 struct EventMask {
 12     int flag;
 13     const char* name;
 14 };
  16 struct EventMask event_masks[] = {
 17     {IN_ACCESS , "IN_ACCESS"} ,
 18     {IN_ATTRIB , "IN_ATTRIB"} ,
 19     {IN_CLOSE_WRITE , "IN_CLOSE_WRITE"} ,
 20     {IN_CLOSE_NOWRITE , "IN_CLOSE_NOWRITE"} ,
 21     {IN_CREATE , "IN_CREATE"} ,
 22     {IN_DELETE , "IN_DELETE"} ,
 23     {IN_DELETE_SELF , "IN_DELETE_SELF"} ,
 24     {IN_MODIFY , "IN_MODIFY"} ,
 25     {IN_MOVE_SELF , "IN_MOVE_SELF"} ,
 26     {IN_MOVED_FROM , "IN_MOVED_FROM"} ,
 27     {IN_MOVED_TO , "IN_MOVED_TO"} ,
 28     {IN_OPEN , "IN_OPEN"} ,
 29     {IN_DONT_FOLLOW , "IN_DONT_FOLLOW"} ,
 30     {IN_EXCL_UNLINK , "IN_EXCL_UNLINK"} ,
 31     {IN_MASK_ADD , "IN_MASK_ADD"} ,
 32     {IN_ONESHOT , "IN_ONESHOT"} ,
 33     {IN_ONLYDIR , "IN_ONLYDIR"} ,
 34     {IN_IGNORED , "IN_IGNORED"} ,
 35     {IN_ISDIR , "IN_ISDIR"} ,
 36     {IN_Q_OVERFLOW , "IN_Q_OVERFLOW"} ,
 37     {IN_UNMOUNT , "IN_UNMOUNT"} ,
 38 };
 39 
 40 int main()
 41 {
 42 
 43 char buf[BUF_LEN];
 44     struct inotify_event *event;
 45     int fd = inotify_init();     //初始化inotify
    //監控PATH目錄下的IN_DELETE | IN_CREATE事件
 46     int state = inotify_add_watch(fd, PATH,IN_DELETE | IN_CREATE); 
 47     while (state > 0) {
     // 通过 read 调用可以一次获得多个事件,只要提供的 buf 足够大;如果沒有事件會一直阻塞在這
 48          size_t len = read (fd, buf, BUF_LEN);
 49          event = (struct inotify_event *)buf;
 50          int i = 0;
 51          for (i=0; i <22; ++i) {
 52          if (event->mask & event_masks[i].flag) {
 53              printf("\t%s\n", event_masks[i].name);
 54          }   
 55          }      
 56     }
 57 }
 15 

Android中PackageManagerService來監控目錄中的apk的更新以及刪除就是用linux下的inotify來實現的,不過它是調用class FileObserver提供的接口, FileObserver也只是對inotify的封裝。

frameworks/base/core/java/android/os/FileObserver.java
 42 public abstract class FileObserver {
......
 88         public int startWatching(String path, int mask, FileObserver observer) {
 89             int wfd = startWatching(m_fd, path, mask);
 90 
 91             Integer i = new Integer(wfd);
 92             if (wfd >= 0) {
 93                 synchronized (m_observers) {
 94                     m_observers.put(i, new WeakReference(observer));
 95                 }
 96             }
 97 
 98             return i;
 99         }
101         public void stopWatching(int descriptor) {
102             stopWatching(m_fd, descriptor);
103         }
131         private native int startWatching(int fd, String path, int mask);
132         private native void stopWatching(int fd, int wfd);

line 89调用startWatching添加一個m_fd監控,line 102调用stopWatching刪除一個m_fd監控,它們都是Jni method

105 static jint android_os_fileobserver_startWatching(JNIEnv* env, jobject object, jint fd, jstring pathString, jint mask)
106 {
107     int res = -1;
108 
109 #ifdef HAVE_INOTIFY
110 
111     if (fd >= 0)
112     {
113         const char* path = env->GetStringUTFChars(pathString, NULL);
114 
115         res = inotify_add_watch(fd, path, mask);
116 
117         env->ReleaseStringUTFChars(pathString, path);
118     }
119 
120 #endif // HAVE_INOTIFY
121 
122     return res;
123 }
124 
125 static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd)
126 {
127 #ifdef HAVE_INOTIFY
128 
129     inotify_rm_watch((int)fd, (uint32_t)wfd);
130 
131 #endif // HAVE_INOTIFY
132 }
133 
134 static JNINativeMethod sMethods[] = {
135      /* name, signature, funcPtr */
136     { "init", "()I", (void*)android_os_fileobserver_init },
137     { "observe", "(I)V", (void*)android_os_fileobserver_observe },
138     { "startWatching", "(ILjava/lang/String;I)I", (void*)android_os_fileobserver_startWatching },
139     { "stopWatching", "(II)V", (void*)android_os_fileobserver_stopWatching }
140 
141 };

startWatching對應的Jni method是android_os_fileobserver_startWatching ,line 115也是调用inotify_add_watch去添加一个fd监控,同樣的stopWatching對應的Jni method是android_os_fileobserver_stopWatching,line 129调用inotify_rm_watch來刪除fd監控。

inotify一些相关函数介绍

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1841次
    • 积分:70
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档