Posted by & filed under Uncategorized.

About Only

Fei Yu has written 50 post in this blog.

可能遇到的问题

android系统自身自带有存储,另外也可以通过sd卡来扩充存储空间。前者好比pc中的硬盘,后者好移动硬盘。 前者空间较小,后者空间大,但后者不一定可用。 开发应用,处理本地数据存取时,可能会遇到这些问题:

  1. 需要判断sd卡是否可用: 占用过多机身内部存储,容易招致用户反感,优先将数据存放于sd卡;
  2. 应用数据存放路径,同其他应用应该保持一致,应用卸载时,清除数据:
    • 标新立异在sd卡根目录建一个目录,招致用户反感
    • 用户卸载应用后,残留目录或者数据在用户机器上,招致用户反感
  3. 需要判断两者的可用空间: sd卡存在时,可用空间反而小于机身内部存储,这时应该选用机身存储;
  4. 数据安全性,本应用数据不愿意被其他应用读写;
  5. 图片缓存等,不应该被扫描加入到用户相册等媒体库中去。

基本操作

  1. 使用外部存储,需要的权限,在AndoridManifest.xml中:

    从API 19 / Andorid 4.4 / KITKAT开始,不再需要显式声明这两个权限,除非要读写其他应用的应用数据($appDataDir)

  2. 判断sd卡可用:

存储的用量情况

  • 根据系统用户不同,所能占用的存储空间大小也有不同

    在API level 9及其以上时,File对象的getFreeSpace()方法获取系统root用户可用空间;

    getUsableSpace()取非root用户可用空间

  • 当有多个存储可用时获取磁盘用量,根据当前系统情况选用合适的存储。
  • 根据系统存储用量,合理设定app所用的空间大小;运行时,也可做动态调整。
  • 在API level 9及其以上的系统,可直接调用File对象的相关方法,以下需自行计算:

路径的规律

一般地,通过Context 和 Environment相关的方法获取文件存取的路径。

通过这两个类可获取各种路径,如图:


各个路径的特性

下面介绍这些路径的特性以及使用中需要注意的细节:

  1. 根目录($rootDir):
    • 内部存储路径: /data, 通过Environment.getDataDirectory() 获取
    • 外部存储路径: /storage/sdcard0 (也有类似 /mnt/ 这样的),通过Environment.getExternalStorageDirectory()获取

      示例:


  2. 应用数据目录($appDataDir)
    • 内部储存: $appDataDir = $rootDir/data/$packageName,
    • 外部存储: $appDataDir = $rootDir/Andorid/data/$packageName

    在这些目录下的数据,在app卸载之后,会被系统删除,我们应将应用的数据放于这两个目录中。


  3. 外部存储中,公开的数据目录。 这些目录将不会随着应用的删除而被系统删除,请斟酌使用:


  4. 应用数据目录下的目录

    一般的在$appDataDir下,会有两个目录

    1. 数据缓存:$cacheDir = $appDataDir/cache:
      • 内部存储:Context.getCacheDir(), 机身内存不足时,文件会被删除
      • 外部存储:Context.getExternalCacheDir()

        外部存储没有实时监控,当空间不足时,文件不会实时被删除,可能返回空对象

        示例:

    2. 文件目录 $filesDir = $appDataDir/files:
      • 内部存储:通过Context.getFilesDir() 获取

        Context.getFileStreamPath(String name)返回以name为文件名的文件对象,name为空,则返回 $filesDir 本身

        示例:

      • 外部存储:通过Context.getExternalFilesDir(String type)type为空字符串时获取.

        type系统指定了几种类型:

        示例:


    3. $cacheDir / $filesDir 安全性

      在内部存储中,$cacheDir$filesDir是app安全的,其他应用无法读取本应用的数据,而外部存储则不是。

      在外部存储中,这两个文件夹其他应用程序也可访问。

      在外部存储中,$filesDir中的媒体文件,不会被当做媒体扫描出来,加到媒体库中。


    4. $cacheDir / $filesDir 同级目录

      在内部存储中:通过 Context.getDir(String name, int mode)可获取和 $filesDir / $cacheDir 同级的目录

      目录的命名规则为 app_ + name, 通过mode可控制此目录为app私有还是其他app可读写。

      示例:


    5. 特别注意, 对于外部存储,获取$cacheDir 或者 $filesDir及其下的路径

      在API level 8 以下,或者空间不足,相关的方法获路径为空时,需要自己构造。

Leave a Reply

  • (will not be published)