2012-04-24 7 views
8

Estoy usando FileObserver para observar un directorio de cambios. El proceso funciona bien el 90% del tiempo, pero ocasionalmente falla.Android FileObserver pasando un evento no documentado 32768

Aquí es un ejemplo de trabajo de Logcat:

04-23 21:12:03.873: V/ItemObserver(1663): Setting up new item observer for item 2 
04-23 21:12:04.374: I/ItemObserver(1663): Received item event for item 2, event: 256, file: batch.get.47 
04-23 21:12:07.866: I/ItemObserver(1663): Received item event for item 2, event: 512, file: batch.get.47 
04-23 21:12:07.873: I/ItemObserver(1663): Received item event for item 2, event: 512, file: item.xml 
04-23 21:12:07.883: I/ItemObserver(1663): Received item event for item 2, event: 256, file: item.xml 
04-23 21:12:08.033: I/ItemObserver(1663): Received item event for item 2, event: 8, file: item.xml 

Aquí está un ejemplo fallido:

04-23 22:08:09.403: V/ItemObserver(1751): Setting up new item observer for item 2 
04-23 22:08:09.813: I/ItemObserver(1751): Received item event for item 2, event: 256, file: batch.get.52 
04-23 22:08:09.954: I/ItemObserver(1751): Received item event for item 2, event: 32768, file: null 

Una vez que tengo el evento 32768 con un archivo nulo, todo se detiene. Revisé el origen de FileObserver y busqué inotify 32768 y no puedo encontrar el lugar al que se hace referencia.

El código para configurar el observador es el siguiente:

itemDirObserver = new FileObserver(getItemsCache().getProcessedItemDir(itemId).getPath(), 
FileObserver.CLOSE_WRITE | FileObserver.CREATE | FileObserver.DELETE) { 
    @Override 
    public void onEvent(int event, final String file) { 
    itemDirChanged(event, file); 
    } 
}; 
itemDirObserver.startWatching(); 

El código para el Logcat es:

public synchronized void itemDirChanged(int event, String file) { 
    Log.i(LOG, "Received item event for item " + itemId + ", event: " + event + ", file: " + file); 
    switch (event) { 
<snip> 

alguna idea de qué 32768 y archivo nulo significa?

+0

Decidí presentar esto como un error: http://code.google.com/p/android/issues/detail?id=29546&q=FileObserver&colspec=ID%20Type%20Status % 20Propietario% 20Summary% 20Stars – mvsjes2

+0

compruebe esta pregunta: http://stackoverflow.com/questions/2452661/file-observer-problem – Ciprian

+0

Gracias. El problema parece ser que, incluso después de invocar a StopWatching, puede obtener múltiples eventos 32768 en su devolución de llamada antes de que su objeto observador sea basura, por lo que necesita admitir eventos en su clase de observador después de haber llamado a detención. OMI, después de llamar a StopWatching, ya no deberías tener que preocuparte más.La clase FileObserver ciertamente necesita ser actualizada para estar más sincronizada con inotify. – mvsjes2

Respuesta

6

Gracias a this answer.

Los códigos de evento se enumeran here.

32768, en particular, es la siguiente:

#define IN_IGNORED 0x00008000/* El archivo fue ignorada */

+0

¿Pero sabes lo que significa "IN_IGNORED" en realidad? ¿Significa que FileObserver ya no lo está viendo? –

+1

No sé mucho al respecto, tbh, pero encontré esto: http://stackoverflow.com/a/4665947/931277. Parece que una causa es la eliminación del nodo. Significa que no recibirás más eventos para ese nodo. – dokkaebi

+1

IN_IGNORED se activa cuando: un reloj inotify se elimina (por ejemplo, cuando se cierra FileObserver), cuando se elimina un archivo (y todos los enlaces duros) o cuando se desmonta la partición, que contiene un archivo (a diferencia de mantener un archivo abierto descriptor, su programa no será eliminado si solo monitorea un archivo a través de inotify). – user1643723

1

yo también sufría de fallos ocasionales.

Descubrí un gran problema con Android FileObserver: no debe tener dos FileObservers viendo la misma carpeta en su aplicación.

Si llama al StopWatching en un FileObserver, cualquier otro FileObserver que esté viendo la misma carpeta también dejará de ver.

+1

Este es un error en 'FileObserver' (tiene muchos más errores que eso ...): si intentas agregar un reloj para un archivo, cuando ya existe otro reloj para ese inodo, Linux inotify API devolverá el reloj existente. Esto no se tiene en cuenta en el código fuente FileObserver. Agregar varios relojes para el mismo archivo/directorio o agregar relojes para diferentes enlaces duros al mismo archivo (que comparten el inodo) desencadenará el comportamiento observado. – user1643723

0

Tuve el problema de que mi FileObserver recibe el evento 32768 y deja de funcionar. Intenté desesperadamente entender cómo solucionar esto (sin volver a crear FileObserver) durante un par de días.

Primero encontré que aunque tengo una referencia difícil a mi FileObserver, este evento (32768) puede ser desencadenado por la recolección de basura (cuando lo forcé a través de DDMS).

Eventualmente encontré que había otro FileObserver en mi programa en la misma carpeta. Tan pronto como lo borré todo comenzó a funcionar.

¿Alguien sabe si es legal tener varios observadores en el mismo directorio? No pude encontrar ninguna información al respecto

Cuestiones relacionadas