FileObserver文件監(jiān)聽

一、概述

FileObserver主要用來提供對文件或者文件夾的監(jiān)控,一個FileObserver實例監(jiān)控一個文件,能夠監(jiān)控的文件或者文件夾的event type包括下表中的幾種。

類型值 類型名稱 含義
1 ACCESS 從文件中讀取數(shù)據(jù)
2 MODIFY 從文件中編輯數(shù)據(jù)
4 ATTRIB 文件元數(shù)據(jù)(權(quán)限,擁有者,時間戳)被明確改變
8 CLOSE_WRITE 有人打開文件或者目錄進行書寫,并且關(guān)閉它
16 CLOSE_NOWEITTE 有人打開文件或者目錄沒有編輯,并且關(guān)閉它
32 OPEN 一個文件或者目錄被打開
64 MOVE_FROM 一個文件或者子目錄從被監(jiān)控目錄被移出
128 MOVE_TO 一個文件或者子目錄被移入到被監(jiān)控的目錄
256 CREATE 一個文件或者子目錄在被監(jiān)控的目錄下被創(chuàng)建
512 DELETE 文件從監(jiān)控目錄被刪除
1024 DELETE_SELF 監(jiān)控的文件或者目錄被刪除,監(jiān)控停止
2048 MOVE_SELF 監(jiān)控的文件或者目錄被移動,監(jiān)控繼續(xù)

另外,在調(diào)試的過程中,FileObserveronEvent會返回未明確定義的event type,經(jīng)過調(diào)試,對應(yīng)的含義如下表。

類型值 含義
1073742080 “文件夾”的創(chuàng)建(Create)操作
1073742336 “文件夾”的刪除(Delete)操作
1073741888 “文件夾”的移出(MOVE_FROM) 操作
1073741952 “文件夾”的移入(MOVE_TO) 操作
32768 “文件夾” 的打開操作 (OPEN) 操作

如果發(fā)現(xiàn)新的類型,后期會進行完善。

二、FileObserver的使用

FileObserver的API相對簡單,可以繼承FileObserver實現(xiàn)自定義的MyFileObserver,目的是監(jiān)控onEvent回調(diào),然后執(zhí)行startWatching啟動監(jiān)控,在需要停止監(jiān)控的時候執(zhí)行stopWatching。

三、FileObserver收不到onEvent回調(diào)

如果在開發(fā)的過程中,遇到onEvent無法接收的問題,先確認(rèn)對以下幾種可能原因進行排除。

  1. FileObserver對象實例被回收 (思路:通過放在Application中進行測試)
  2. 初始化順序問題 (思路:盡早的對FileObserver進行初始化)
  3. 沒有讀寫文件權(quán)限問題 (思路: 文件監(jiān)控需要文件讀寫權(quán)限)
  4. onEvent中做復(fù)雜操作 (思路: 先跑通,再實現(xiàn)邏輯)
  5. 妨礙 inotify的可能性
  6. 同一個進程中,如果有兩個不同的FileObserver同時監(jiān)控一個Path,只有后調(diào)用startWatching的FileObserver能夠收到onEvent回調(diào)。(Android系統(tǒng)Bug)

我在開發(fā)的過程中,最終是最后一點導(dǎo)致的,這是Android framework的Bug,Android系統(tǒng)Bug地址,解決方案在地址中有提供。

四、FileObserver使用注意事項

因為FileObserverstartWatchingstopWatching都存在加鎖操作。拿startWatching源碼舉例。

public int startWatching(String path, int mask, FileObserver observer) {
    int wfd = startWatching(m_fd, path, mask);
    Integer i = new Integer(wfd);
     if (wfd >= 0) {
         synchronized (m_observers) {
              m_observers.put(i, new WeakReference(observer));
         }
    }
    return i;
}

其中有m_observers對象鎖,所有在我們調(diào)用MyFileObserverstartWatching時,盡量不要放在自己實現(xiàn)的對象鎖中實現(xiàn),可能會引發(fā)死鎖操作,從而導(dǎo)致ANR。思路如下:

public class MyFileObserver extends FileObserver{
   @Override
    public void onEvent(int event0, String path) {
     // TODO 處理自己的業(yè)務(wù)邏輯
   }
}

public class FileObserverTest{
     private static final Object ob_lock = new Object();
     public void  startWatching(String path){
           MyFileObserver observer = new MyFileObserver(path)
           observer.startWatching();
           synchronized(ob_lock){
                // TODO 這里去執(zhí)行程序中需要枷鎖進行同步的操作,不要將startWatching放在業(yè)務(wù)邏輯鎖中,防止死鎖。
           }
     }
}

五、FileObserver總結(jié)

文件操作相關(guān)的開發(fā)中,經(jīng)常會用到FileObserver對文件的監(jiān)控操作,從而去實現(xiàn)當(dāng)文件有變化時,程序及時進行UI邏輯反饋給用戶的能力,上面我列出了自己在使用過程中的一些經(jīng)驗和總結(jié),如果有遺留的思路或者問題,歡迎進行留言反饋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,175評論 25 708
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,045評論 2 59
  • 喜歡劉方平的這句詩“寂寞空庭春欲晚,梨花滿地不出門?!毕矚g詩句里那份似乎帶著點點花香的寂寞。 習(xí)慣了人來人往,...
    盛世回首閱讀 200評論 0 0
  • 寶寶日記寶寶濕疹。 寶寶最初的濕疹,是從月子里面開始的。月子里面寶寶臉上會有一個個紅色的小米粒點點,一直以為是奶滴...
    最美的時光在路上閱讀 258評論 1 0
  • 2015年10月22日 昨天去九院終于約上了拔智齒的日子,明年的1月20日,不愧是上海第一的拔牙醫(yī)院,直接是三個月...
    大臉的白菜閱讀 1,583評論 1 50

友情鏈接更多精彩內(nèi)容