星期三, 7月 20, 2011

儲存空間即將不足

都上 SD Card,加裝 Link2SD 了,才裝幾個程式,Android 手機就開始唉唉叫,左上角老是出現"儲存空間即將不足"的訊息,真的是太令人生氣。本來不想挖程式出來看的,唉~

Android 程式的文字多半是存在 xml 檔案,也就是 resource 檔,關鍵是在於對應所使用的變數名稱。在 mydroid 目錄下先用 source build/envsetup.sh ,再用 resgrep '儲存空間即將不足' 來找,出現這段文字的檔案有兩個,不過很明顯,變數名稱應該是 low_internal_storage_view_title。

再用 jgrep 去找:jgrep low_internal_storage_view_title ,排除掉 R.java 之後,可以看到一個不一樣的:frameworks/base/services/ajva/com/android/server/DeviceStorageMonitorService.java

看來關鍵就在這檔案裡了。從裏面可以看到在 sendNotification 裡,會把 low_internal_storage_view_title 當作訊息丟出去,於是上方的通知欄就有了'儲存空間即將不足的訊息'。那麼是在那邊去 sendNotification 的呢? 是同個檔案裡的 checkMemory()。

checkMemory() 裡的檢查邏輯很簡單,先 getMemThreshold(),再用 mFreeMem 去做判斷,如果比取到的 threshold 值要小,mLowMemFlag 還沒設為true,就先試著清理 cache,再不行,就 sendNotification。

getMemThreshold() 是怎麼取 threshold 的呢?是從 Content Resolver 裡找 "sys_storage_threshold_percentage" 來的,如果沒取到,則以 10 為預設值,然後乘上 mTotalMemory。

好,上面有幾個關鍵的變數:mTotalMemory、mFreeMem,這兩個變數又是怎麼來的?checkMemory() 裡在檢查 mFreeMem 之前,有先呼叫 restatDataDir(),這個函數會呼叫到底層的 C 函數 - statfs 來取得 /data 的資訊,statfs 回傳一個結構體,主要會使用到裏面的 f_bavail、f_bsize、f_blocks。mFreeMem = f_bavail * f_bsize; mTotalMemory = f_blocks * f_bsize。

從上面的資訊看來,如果要避免不足的問題,要不就是增加 /data 的可用空間,要不就是降低 threshold 的值。但原始碼裡透露了另外一個密技,restatDataDir() 裡,在使用 statfs 取得資訊以後,接著去取 System properties 裡的 debug.freemem,如果有取到,就拿這個當作 mFreeMem 的值來用。看來是可以利用的喔~搭配 setprop 可以設置 debug.freemem ,不過需要 root 嗎? 待驗證。

沒有留言: