歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android檢查存儲空間小結

Android檢查存儲空間小結

日期:2017/3/1 11:00:57   编辑:Linux編程

Android手機上面的存儲空間主要有手機本身的存儲空間和SD卡的存儲空間。之前用的最多的是SD卡的存儲空間,在總結的時候看了一下系統的源代碼,很有收獲。在手機安裝應用時,系統會自動在/data/data目錄下面以應用的主包名創建一個目錄,默認還會在最後的那個目錄裡面創建一個lib目錄。下面看一下系統獲取存儲空間的代碼:

來自android2.3.3系統源代碼/packages/apps/Settings/src/com/android/settings/applications/ManageApplications.java

  1. 531.mDataFileStats = new StatFs("/data");
  2. 532.mSDCardFileStats = new StatFs(Environment.getExternalStorageDirectory().toString());
  1. <pre name="code" class="java">748.mDataFileStats.restat("/data");
  2. try {
  3. totalStorage = (long)mDataFileStats.getBlockCount() *
  4. mDataFileStats.getBlockSize();
  5. freeStorage = (long) mDataFileStats.getAvailableBlocks() *
  6. mDataFileStats.getBlockSize();
  7. } catch (IllegalArgumentException e) {
  8. }
  9. final int N = mApplicationsAdapter.getCount();
  10. for (int i=0; i<N; i++) {
  11. ApplicationsState.AppEntry ae = mApplicationsAdapter.getAppEntry(i);
  12. appStorage += ae.codeSize + ae.dataSize;
  13. }
  14. freeStorage += mApplicationsState.sumCacheSizes();<pre name="code" class="java"><pre>




 
  1. 734.mSDCardFileStats.restat(Environment.getExternalStorageDirectory().toString());
  2. try {
  3. totalStorage = (long)mSDCardFileStats.getBlockCount() * mSDCardFileStats.getBlockSize();
  4. freeStorage = (long) mSDCardFileStats.getAvailableBlocks() * mSDCardFileStats.getBlockSize();
  5. } catch (IllegalArgumentException e) {
  6. // use the old value of mFreeMem
  7. }
第531行代碼是計算系統的空間,第532行是檢查SD卡的空間。可以看出,系統檢查的是/data目錄下面的空間。手機都有一個參數ROM,那麼ROM指的是什麼空間?比如說G7,ROM是512M,那麼空間是怎麼分配的呢?還好手中的G7有root權限,不知道以下的操作需不需要root權限,有手機的同學可以試試。找到SDK中adb.exe文件所在目錄,2.3以前的是在tools目錄中,以後是在platform-tools目錄中,從命令行中進入到該目錄。如果配置了環境變量就不需要,直接啟動命令行窗口執行adb shell,就會進入系統文件目錄,然後執行df,就會看到一些信息,下面是G7(也可以用模擬器試試)的信息:

Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 207628 32 207596 0% /dev
tmpfs 207628 0 207628 0% /mnt/asec
tmpfs 207628 0 207628 0% /mnt/obb
/dev/block/mtdblock3 256000 145736 110264 57% /system
/dev/block/mtdblock5 151168 102396 48772 68% /data
/dev/block/mtdblock4 40960 1204 39756 3% /cache
/dev/block/vold/179:1
942848 49232 893616 5% /mnt/sdcard
/dev/block/vold/179:1
942848 49232 893616 5% /mnt/secure/asec

可以看出有一個分區是掛載到了/data目錄下面,已經使用了48772K,還剩102396K,也就是512M的ROM最後系統只給用戶分配151168K,不足150M,其余的被系統占用,其它的就不說了,不敢在linux大神面前班門弄斧。從上面的代碼可以看出,系統給應用還有一定的緩存空間,最後還被計算到可用空間中去了。看過的同學可以用下面的代碼測試一下,獲取/data目錄和/data/data目錄下面的空間會不一樣,有一點點小差別,貌似應該就是緩存空間吧。SD卡就不說了,從上面的信息也可以看出來,SD卡有1個G,掛載在/mnt/sdcard目錄下面。

下面是個人整理的檢查手機的存儲空間的有關代碼,僅供參考。

  1. <pre name="code" class="java"><pre name="code" class="java">
  2. import java.io.File;
  3. import android.os.Environment;
  4. import android.os.StatFs;
  5. /**
  6. * 存儲空間管理
  7. * @author [email protected]
  8. *
  9. */
  10. public class MemorySpaceCheck
  11. {
  12. /**
  13. * 計算剩余空間
  14. * @param path
  15. * @return
  16. */
  17. private static long getAvailableSize(String path)
  18. {
  19. StatFs fileStats = new StatFs(path);
  20. fileStats.restat(path);
  21. return (long) fileStats.getAvailableBlocks() * fileStats.getBlockSize(); // 注意與fileStats.getFreeBlocks()的區別
  22. }
  23. /**
  24. * 計算總空間
  25. * @param path
  26. * @return
  27. */
  28. private static long getTotalSize(String path)
  29. {
  30. StatFs fileStats = new StatFs(path);
  31. fileStats.restat(path);
  32. return (long) fileStats.getBlockCount() * fileStats.getBlockSize();
  33. }
  34. /**
  35. * 計算SD卡的剩余空間
  36. * @return 剩余空間
  37. */
  38. public static long getSDAvailableSize()
  39. {
  40. if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
  41. {
  42. return getAvailableSize(Environment.getExternalStorageDirectory().toString());
  43. }
  44. return 0;
  45. }
  46. /**
  47. * 計算系統的剩余空間
  48. * @return 剩余空間
  49. */
  50. public static long getSystemAvailableSize()
  51. {
  52. // context.getFilesDir().getAbsolutePath();
  53. return getAvailableSize("/data");
  54. }
  55. /**
  56. * 是否有足夠的空間
  57. * @param filePath 文件路徑,不是目錄的路徑
  58. * @return
  59. */
  60. public static boolean hasEnoughMemory(String filePath)
  61. {
  62. File file = new File(filePath);
  63. long length = file.length();
  64. if (filePath.startsWith("/sdcard") || filePath.startsWith("/mnt/sdcard"))
  65. {
  66. return getSDAvailableSize() > length;
  67. }
  68. else
  69. {
  70. return getSystemAvailableSize() > length;
  71. }
  72. }
  73. /**
  74. * 獲取SD卡的總空間
  75. * @return
  76. */
  77. public static long getSDTotalSize()
  78. {
  79. if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
  80. {
  81. return getTotalSize(Environment.getExternalStorageDirectory().toString());
  82. }
  83. return 0;
  84. }
  85. /**
  86. * 獲取系統可讀寫的總空間
  87. * @return
  88. */
  89. public static long getSysTotalSize()
  90. {
  91. return getTotalSize("/data");
  92. }
  93. }
如果想要在系統的存儲空間中寫入數據,可以用context.getFilesDir().getAbsolutePath(),獲取該應用的可寫目錄,也就是/data/data/應用主包名/files目錄,可以往裡面寫入數據,在應用被卸載時,也一並被刪除,不用擔心會產生垃圾,灰常給力。如果不妥之處,歡迎批評指正! 

			
Copyright © Linux教程網 All Rights Reserved