Last active
August 29, 2015 14:05
-
-
Save guileen/59d2cca8a17ac6813672 to your computer and use it in GitHub Desktop.
http://www.cnblogs.com/zealotrouge/p/3159772.html 思路是今天想到了一个Android自API1就有的一个类FileObserver,这个类用于监听某个文件的变化状态,如果是目录,这个类还可以监听其子目录及子目录文件的变化状态,通过阅读FileObserver源码,发现其实现利用了Linux内核中一个重要的机制inotify,它是一个内核用于通知用户空间程序文件系统变化的机制
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 头文件begin */ | |
#include "main_activity_UninstalledObserverActivity.h" | |
/* 头文件end */ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/* 内全局变量begin */ | |
static char c_TAG[] = "UninstalledObserverActivity.init"; | |
static jboolean b_IS_COPY = JNI_TRUE; | |
/* 内全局变量 */ | |
/* | |
* Class: main_activity_UninstalledObserverActivity | |
* Method: init | |
* Signature: ()V | |
*/ | |
JNIEXPORT void JNICALL Java_main_activity_UninstalledObserverActivity_init(JNIEnv *env, jobject obj) | |
{ | |
jstring tag = (*env)->NewStringUTF(env, c_TAG); | |
//初始化log | |
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "init OK"), &b_IS_COPY)); | |
//fork子进程,以执行轮询任务 | |
pid_t pid = fork(); | |
if (pid < 0) | |
{ | |
//出错log | |
LOG_ERROR((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "fork failed !!!"), &b_IS_COPY)); | |
} | |
else if (pid == 0) | |
{ | |
//子进程注册"/data/data/pym.test.uninstalledobserver"目录监听器 | |
int fileDescriptor = inotify_init(); | |
if (fileDescriptor < 0) | |
{ | |
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_init failed !!!"), &b_IS_COPY)); | |
exit(1); | |
} | |
int watchDescriptor; | |
watchDescriptor = inotify_add_watch(fileDescriptor, "/data/data/pym.test.uninstalledobserver", IN_DELETE); | |
if (watchDescriptor < 0) | |
{ | |
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "inotify_add_watch failed !!!"), &b_IS_COPY)); | |
exit(1); | |
} | |
//分配缓存,以便读取event,缓存大小=一个struct inotify_event的大小,这样一次处理一个event | |
void *p_buf = malloc(sizeof(struct inotify_event)); | |
if (p_buf == NULL) | |
{ | |
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "malloc failed !!!"), &b_IS_COPY)); | |
exit(1); | |
} | |
//开始监听 | |
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "start observer"), &b_IS_COPY)); | |
size_t readBytes = read(fileDescriptor, p_buf, sizeof(struct inotify_event)); | |
//read会阻塞进程,走到这里说明收到目录被删除的事件,注销监听器 | |
free(p_buf); | |
inotify_rm_watch(fileDescriptor, IN_DELETE); | |
//目录不存在log | |
LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY) | |
, (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "uninstalled"), &b_IS_COPY)); | |
//执行命令am start -a android.intent.action.VIEW -d http://shouji.360.cn/web/uninstall/uninstall.html | |
execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "http://shouji.360.cn/web/uninstall/uninstall.html", (char *)NULL); | |
} | |
else | |
{ | |
//父进程直接退出,使子进程被init进程领养,以避免子进程僵死 | |
} | |
} | |
#ifdef __cplusplus | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 头文件begin */ | |
#include <jni.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <android/log.h> | |
#include <unistd.h> | |
#include <sys/inotify.h> | |
#include <fcntl.h> | |
/* 头文件end */ | |
/* 宏定义begin */ | |
//清0宏 | |
#define MEM_ZERO(pDest, destSize) memset(pDest, 0, destSize) | |
//LOG宏定义 | |
#define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg) | |
#define LOG_DEBUG(tag, msg) __android_log_write(ANDROID_LOG_DEBUG, tag, msg) | |
#define LOG_WARN(tag, msg) __android_log_write(ANDROID_LOG_WARN, tag, msg) | |
#define LOG_ERROR(tag, msg) __android_log_write(ANDROID_LOG_ERROR, tag, msg) | |
/* 宏定义end */ | |
#ifndef _Included_main_activity_UninstalledObserverActivity | |
#define _Included_main_activity_UninstalledObserverActivity | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
#undef main_activity_UninstalledObserverActivity_MODE_PRIVATE | |
#define main_activity_UninstalledObserverActivity_MODE_PRIVATE 0L | |
#undef main_activity_UninstalledObserverActivity_MODE_WORLD_READABLE | |
#define main_activity_UninstalledObserverActivity_MODE_WORLD_READABLE 1L | |
#undef main_activity_UninstalledObserverActivity_MODE_WORLD_WRITEABLE | |
#define main_activity_UninstalledObserverActivity_MODE_WORLD_WRITEABLE 2L | |
#undef main_activity_UninstalledObserverActivity_MODE_APPEND | |
#define main_activity_UninstalledObserverActivity_MODE_APPEND 32768L | |
#undef main_activity_UninstalledObserverActivity_MODE_MULTI_PROCESS | |
#define main_activity_UninstalledObserverActivity_MODE_MULTI_PROCESS 4L | |
#undef main_activity_UninstalledObserverActivity_BIND_AUTO_CREATE | |
#define main_activity_UninstalledObserverActivity_BIND_AUTO_CREATE 1L | |
#undef main_activity_UninstalledObserverActivity_BIND_DEBUG_UNBIND | |
#define main_activity_UninstalledObserverActivity_BIND_DEBUG_UNBIND 2L | |
#undef main_activity_UninstalledObserverActivity_BIND_NOT_FOREGROUND | |
#define main_activity_UninstalledObserverActivity_BIND_NOT_FOREGROUND 4L | |
#undef main_activity_UninstalledObserverActivity_BIND_ABOVE_CLIENT | |
#define main_activity_UninstalledObserverActivity_BIND_ABOVE_CLIENT 8L | |
#undef main_activity_UninstalledObserverActivity_BIND_ALLOW_OOM_MANAGEMENT | |
#define main_activity_UninstalledObserverActivity_BIND_ALLOW_OOM_MANAGEMENT 16L | |
#undef main_activity_UninstalledObserverActivity_BIND_WAIVE_PRIORITY | |
#define main_activity_UninstalledObserverActivity_BIND_WAIVE_PRIORITY 32L | |
#undef main_activity_UninstalledObserverActivity_BIND_IMPORTANT | |
#define main_activity_UninstalledObserverActivity_BIND_IMPORTANT 64L | |
#undef main_activity_UninstalledObserverActivity_BIND_ADJUST_WITH_ACTIVITY | |
#define main_activity_UninstalledObserverActivity_BIND_ADJUST_WITH_ACTIVITY 128L | |
#undef main_activity_UninstalledObserverActivity_CONTEXT_INCLUDE_CODE | |
#define main_activity_UninstalledObserverActivity_CONTEXT_INCLUDE_CODE 1L | |
#undef main_activity_UninstalledObserverActivity_CONTEXT_IGNORE_SECURITY | |
#define main_activity_UninstalledObserverActivity_CONTEXT_IGNORE_SECURITY 2L | |
#undef main_activity_UninstalledObserverActivity_CONTEXT_RESTRICTED | |
#define main_activity_UninstalledObserverActivity_CONTEXT_RESTRICTED 4L | |
#undef main_activity_UninstalledObserverActivity_RESULT_CANCELED | |
#define main_activity_UninstalledObserverActivity_RESULT_CANCELED 0L | |
#undef main_activity_UninstalledObserverActivity_RESULT_OK | |
#define main_activity_UninstalledObserverActivity_RESULT_OK -1L | |
#undef main_activity_UninstalledObserverActivity_RESULT_FIRST_USER | |
#define main_activity_UninstalledObserverActivity_RESULT_FIRST_USER 1L | |
#undef main_activity_UninstalledObserverActivity_DEFAULT_KEYS_DISABLE | |
#define main_activity_UninstalledObserverActivity_DEFAULT_KEYS_DISABLE 0L | |
#undef main_activity_UninstalledObserverActivity_DEFAULT_KEYS_DIALER | |
#define main_activity_UninstalledObserverActivity_DEFAULT_KEYS_DIALER 1L | |
#undef main_activity_UninstalledObserverActivity_DEFAULT_KEYS_SHORTCUT | |
#define main_activity_UninstalledObserverActivity_DEFAULT_KEYS_SHORTCUT 2L | |
#undef main_activity_UninstalledObserverActivity_DEFAULT_KEYS_SEARCH_LOCAL | |
#define main_activity_UninstalledObserverActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L | |
#undef main_activity_UninstalledObserverActivity_DEFAULT_KEYS_SEARCH_GLOBAL | |
#define main_activity_UninstalledObserverActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L | |
/* | |
* Class: main_activity_UninstalledObserverActivity | |
* Method: init | |
* Signature: ()V | |
*/ | |
JNIEXPORT void JNICALL Java_main_activity_UninstalledObserverActivity_init(JNIEnv *, jobject); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment