2012-04-24 2 views
8

변경 사항을 위해 디렉토리를 관찰하기 위해 FileObserver을 사용하고 있습니다. 이 프로세스는 90 %의 시간 동안 정상적으로 작동하지만 때로는 실패합니다. 여기Android FileObserver가 문서화되지 않은 이벤트를 전달합니다. 32768

는 로그 캣의 작업 예입니다

내가 널 파일로 32768 이벤트를 일단
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 

이 모든 것이 정지 :

여기
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 

실패한 예입니다. 내가 FileObserver에 대한 소스를 확인하고 inotify 32768에 대한 검색이 어디에 참조되어 있는지 찾을 수 없습니다.

관찰자를 설정하는 코드는 다음과 같습니다

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(); 

로그 캣의 코드는 다음과 같습니다

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

어떤 생각이 무엇 32768 및 널 (null) 파일을 의미?

+0

이 파일을 버그로 신고하기로 결정했습니다. http://code.google.com/p/android/issues/detail?id=29546&q=FileObserver&colspec=ID%20Type%20Status % 20Owner % 20Summary % 20Stars – mvsjes2

+0

이 질문에 대한 답변 : http://stackoverflow.com/questions/2452661/file-observer-problem – Ciprian

+0

Thanks. 문제는 stopWatching이 호출 된 후에도 옵저버 객체가 가비지 수집되기 전에 콜백에서 여러 개의 32768 이벤트를 얻을 수 있으므로 stopWatching을 호출 한 후 옵저버 클래스에서 이벤트를 처리해야합니다. IMO, stopWatching이 호출 된 후에 더 이상 걱정할 필요가 없습니다.FileObserver 클래스는 확실히 inotify와 동기화되도록 업데이트해야합니다. – mvsjes2

답변

6

덕분에 this answer.

이벤트 코드는 here입니다. 특히

32768 은 이것이다 :

#DEFINE IN_IGNORED 0x00008000/* 파일이 무시 */

+0

하지만 'IN_IGNORED'가 실제로 무엇을 의미하는지 알고 있습니까? fileobserver가 더 이상보고 있지 않다는 의미입니까? –

+1

그것에 대해 많이 알지는 못하지만, 이것을 발견했습니다 : http://stackoverflow.com/a/4665947/931277. 노드가 삭제되는 이유 중 하나 인 것 같습니다. 해당 노드에 대한 추가 이벤트를 수신하지 않는다는 의미입니다. – dokkaebi

+1

IN_IGNORED는 inotify watch가 제거 된 경우 (예 : FileObserver가 닫힌 경우), 파일 (및 모든 하드 링크)이 삭제되거나 파일을 포함하는 파티션이 마운트 해제 된 경우 (열려있는 파일 설명자를 사용하면 inotify를 통해 파일을 모니터링하는 경우 프로그램이 종료되지 않습니다. – user1643723

1

나도 가끔 실패로 고통했다.

Android FileObserver에서 큰 문제가 있음을 발견했습니다. 애플리케이션에서 동일한 폴더를보고있는 두 개의 FileObservers가 없어야합니다.

하나의 FileObserver에서 StopWatching을 호출하면 동일한 폴더를보고있는 다른 FileObserver도 감시를 중지합니다.

+1

이것은'FileObserver'의 버그입니다. (그보다 더 많은 버그가 있습니다 ...) : 파일에 대한 watch를 추가하려고하면, 그 inode에 대한 다른 watch가 이미 존재할 때, Linux inotify API는 기존 watch를 리턴 할 것입니다. 이것은 FileObserver 소스 코드에서 설명되지 않습니다. 동일한 파일/디렉토리에 대해 여러 개의 워치를 추가하거나 동일한 파일 (inode를 공유)에 대한 다른 하드 링크의 워치를 추가하면 관찰 된 동작이 트리거됩니다. – user1643723

0

내 FileObserver가 32768 이벤트를 받고 작동을 멈추는 문제가있었습니다. 며칠 동안 FileObserver를 수정하지 않고이 문제를 해결하는 방법을 필사적으로 시도했습니다.

처음에는 FileObserver에 대한 하드 참조가 있지만이 이벤트 (32768)는 가비지 수집에 의해 트리거 될 수 있다는 것을 알았습니다 (DDMS를 통해 강제 적용했을 때).

결국 내 프로그램에서 동일한 폴더에 다른 FileObserver가 있음을 발견했습니다. 내가 그것을 삭제하자마자 모든 것이 작동하기 시작했다.

동일한 디렉토리에 여러명의 옵저버가 합법적인지 아는 사람이 있습니까?

관련 문제