在Android 官方开发文档中有一篇文档来介绍如何保存应用的数据,但笔者用过很多程序(从知名的到不知名的)处理的都不是很完美,或者 没有按照Android 开发团队建议的方式去保存他们应用的数据。当一些试用过的软件卸载后,在SDCard中还保留了这些软件的文件目录,时间一长就有很多目录需要手工去清理,并且很难确认那些目录是仍然在使用的 那些目录已经没用了,给用户带来困扰。这里我们来讨论下该如何正确的保存应用的数据。

首先数据分为两种:和应用相关的数据;和应用无关的数据。这里分别介绍:

应用无关的数据是那些用户比较关心的数据,不管您的应用在不在用户设备上,这些数据用户都希望保留,这些数据包含:用相机拍摄的照片、用浏览器(下载工具)下载的文件、用户制作的个性铃声等。
假设您开发了一个照相应用(例如: 360相机),用户用您的应用拍摄并处理过的照片就属于应用无关的数据,如果用户把您的应用给卸载了,用户还是会期望仍然保留他们拍摄并处理过的照片。这里的照片按照Android官方的建议应该保存到 DIRECTORY_PICTURES 目录中,该目录通过Environment.getExternalStoragePublicDirectory(String type)来获取,您可以在该目录下创建一个以您的程序命名的目录来保存数据。其他支持的目录列表。

应用相关的数据: 这种数据只和您的应用相关,如果您的应用被用户删除了这些数据也没有理由还存在用户设备中。这种数据包含:数据库文件、属性配置文件、应用的缓存文件等。这种数据可以有很多种保存方式,详情参考这里。
这里我们只讨论在API 8(Android 2.2)中新引入了一种保存到外部存储空间的伪私有数据API,通过函数getExternalFilesDir() 来获取该路径,同样可以设置获取各种类型数据的参数,例如 DIRECTORY_MUSIC 和 DIRECTORY_RINGTONES (如果参数为null则返回您应用数据的跟目录)。比如一个应用的包名为 org.goodev.test 的应用,通过函数getExternalFilesDir(Environment.DIRECTORY_MOVIES)获取到的文件路径为
/storage/sdcard0/Android/data/org.goodev.test/files/Movies。
细心的读者已经发现,该数据目录为SDCard (外部存储设备,有可能是内置SDCard 比如 Nexus S) 中名字为 Android 的根目录下,该目录下有个用来保存应用数据的 data 目录,在这个 data 目录中保存了设备中各个应用的数据,依包名来命名,如果设置参数为null则返回的是跟目录:/storage/sdcard0/Android/data/org.goodev.test/files。
为啥这个目录我们称之为伪私有数据目录呢? 因为在2.2以上的系统中,当您的应用被用户卸载的时候,保存在这个目录下的数据也会被系统删除;并且在默认情况下多媒体扫描器不会扫描该目录下的图片、MP3等多媒体文件– 从这个角度看这个目录是应用的私有数据目录。 由于该目录存在于外部存储空间中,任何其他具有读写外部存储空间权限的应用都可以访问您的应用数据 — 从这个角度看这些数据又不是私有的。 所以我们就称之为 伪私有数据。
那么为什么Android在2.2中引入这种伪私有数据保存方式呢? 这样应用的数据不是很不安全吗? 这种存储方式适合保存那些数据呢? 下面我们来逐个分析下这些问题:
为何引入这种存储方式?
有些Android应用在使用过程中,可能会产生很多需要保存的文件数据,而这些数据需要在应用卸载的时候被删除掉,按照2.2之前的方式,这种需求的数据只能保存到内部存储空间中,而系统的内部存储空间都是有限的,为了让用户能在有限的存储空间中安装更多的应用,所以出现了这种存储方式。个人观点仅供参考 \(^o^)/~。
存储在伪私有目录的数据是不是很不安全?
当然是不安全的,任何应用都有可能访问这些数据,所以一般而言这里只保存那些不是非常敏感的数据,由于这些目录中的数据有可能被用户或者其他应用删除掉,所以在使用这里面的数据的时候要先检测下数据是否存在、有效,如果无效则需要从新下载使用。
这种存储方式适合那些数据呢?
比如一个图片浏览类的应用,用该目录来保存系统图片的缩略图方便提高应用浏览图片的流畅度;或者图书类应用用来保存图书的封面图片等。
如果您的应用运行在旧的设备(低于2.2的版本)上,则您也应该按照上面的建议把文件保存到 /Android/data//files/ 目录下,这样如果用户更新的设备版本后,这些数据就随着应用的卸载而被删除掉了。
遗留问题
当然也有一些比较有争议的数据,比如 IM聊天软件接收到的图片和自定义表情数据 应该保存到SDCard中呢还是上面介绍的 伪私有数据 存储目录中呢? 如果用户卸载了聊天软件,用户是否期望继续保存他们接收到的图片和自定义表情图片呢? 这个问题恐怕针对不同的用户得到的答案是不一样的。这时,我们咋办??
个人建议针对这种没有明确界限的需求,可以在用户第一次使用程序的时候,引导用户去设置他们的这些数据保存到哪里?保存到外部存储空间(应用卸载后数据依然存在);或者保存到应用外部存储目录中(应用卸载后数据自动删除)。 这种做法类似下载一些PC软件的做法,比如一些软件在卸载的时候会填出对话框让用户选择是否保留用户数据。只不过在Android系统中卸载应用目前没办提供该功能,所以只能在应用第一次使用的时候 让用户知道有这么个设置项。
PS:笔者目前最反感的就是一些应用下载了很多小图片到SDCard中,然后打开图库应用会发现里面有很多这种小图片(比如人的头像啦、物品缩略图啦、图书封面图片啦),这种数据就不应该出现在用户的图库应用中去。 如果把这些数据保存到上述的伪私有数据目录中则 就不会出现这种问题。 目前为了避免这种问题,笔者不得不自己在各种目录中创建“.nomedia”文件。相当繁琐啦!

Android如何正确的保存文件的更多相关文章

  1. Android学习笔记_6_保存文件到SDCard

    一.加入访问sdcard的权限 Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态 ...

  2. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  3. 【Android Developers Training】 25. 保存文件

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. [android] 保存文件到手机内存

    /*****************2016年5月4日 更新*******************************/ 知乎:Android 没有沙盒保护机制吗,WhatsApp 信息为何可被随 ...

  5. Android Developers:保存文件

    Android使用一个和其它平台基于硬盘文件系统相似的文件系统.这个课程描述了如何和在Android文件系统使用File APIs读和写文件. 一个File对象适用于读或者写从头到尾没用中断的大型数据 ...

  6. android 保存文件的各种目录列表

    一般的,我们可以通过context和Environment来获取要保存文件的目录 ($rootDir) +- /data -> Environment.getDataDirectory() | ...

  7. Android 读取和保存文件(手机内置存储器)

    1:activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/androi ...

  8. Android学习笔记——保存文件(Saving Files)

              本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论.                 欢迎转载,转载请注明网址:http://www.cnblogs.com/J ...

  9. Android -- 保存文件

    背景                                                                                             我们以常见 ...

随机推荐

  1. centos6.7 install chrome

    1.yum仓库 (如果用rpm包安装 可以忽略此步) vim /etc/yum.repos.d/google-chrome.repo [google-chrome] name=google-chrom ...

  2. CentOS7上Nginx的使用

    Nginx 的启动 指定配置文件的方式启动nginx # nginx -c /etc/nginx/nginx.conf 对于yum安装的nginx,使用systemctl命令启动 # systemct ...

  3. Go语言学习资料汇总

    网站: Go语言官网(访问)(中文镜像) Go语言中文网(访问) Go编译器(访问) Go语言中国社区(访问) golanghome(访问) GoLang中国(访问) Gopher Academic( ...

  4. (转)JS获取当前对象大小以及屏幕分辨率等

    Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> ...

  5. CSS画三角形引发的一些思考

      今天刷知乎时看到了一个问题,有谁能详细讲一下css如何画出一个三角形?怎么想都想不懂? - 知乎.很巧,刚入前端坑的我前不久也遇到过这个问题,今天再来谈一谈这个问题则是因为知乎的一些答案引发了我的 ...

  6. C#DbHelperOra,Oracle数据库帮助类 (转载)

    主要功能如下数据访问抽象基础类 主要是访问Oracle数据库主要实现如下功能 .数据访问基础类(基于Oracle),主要是用来访问Oracle数据库的. .得到最大值:是否存在:是否存在(基于Orac ...

  7. java - 异常浅谈

    java提供异常处理机制中,可以分为RuntimeException和checked Exception两种. RuntimeException 是运行时异常,是程序本身无法解决的.例如,对于一个用户 ...

  8. 这次是C#中的接口

    接口的出现,是为了解决C#中不允许多重继承的问题. 1.什么是接口? 我觉得可以把接口理解为对一组方法声明进行的统一命名,但这些方法没有提供任何实现. 通过接口,就可以对方法进行统一管理,避免了在每种 ...

  9. .NET 互操作

    首先推荐一本书<精通.NET 互操作> ,这本书是目前中文资料里讲 互操作最详尽的书了. 做系统集成项目的同学应该都和设备打过交道(如视频设备:海康.大华等),在大多数情况下这些设备厂商会 ...

  10. angular2 组件之间通讯-使用服务通讯模式 2016.10.27 基于正式版ng2

    工作中用到ng2的组件通讯 奈何官方文档言简意赅 没说明白 自己搞明白后 整理后分享下 rxjs 不懂的看这篇文章 讲很详细 http://www.open-open.com/lib/view/ope ...