博客
关于我
Android开发-API指南-数据存储
阅读量:483 次
发布时间:2019-03-06

本文共 6653 字,大约阅读时间需要 22 分钟。

Storage Options

英文原文:

采集日期:2015-02-06

存储方式概述

  • 用于简单数据的 Shared Preference
  • 用于私有数据的内部存储
  • 用于大型公开数据的外部存储
  • 用于结构化数据的 SQLite 数据库

在本文中

参阅

Android 为永久性保存数据提供了多种方案。 请根据需求来选择存储方式,比如数据是否为应用程序私有的,还是可以供其他应用(用户)访问的,需要多大的存储空间等等。

数据存储方案包括以下几种:

以键-值对(key-value pairs)的形式保存私有的简单(primitive)类型数据。
在设备的内部存储中保存私有数据。
在公用的外部存储中保存公共数据。
在私有的数据库中保存结构化数据。
在自己的 Web 服务器上存放数据

如果需要向其他应用程序公开私有数据, Android 提供了一种途径—— 。根据对数据的访问受限需求,Content Provider 可以自由设定读/写权限。 关于 Content Provider 的更多信息,请参阅 的文档。

使用 Shared Preferences


类提供了一种存储方式,可以用键-值对的方式读写简单类型的数据。用 可以保存任何简单类型的数据:boolean、float、int、long 和 string 。 这些数据是持久保存的,可以跨越用户会话(即使应用程序被杀死了也没关系)。

获得 对象的方法有两种:

  • —— 如果需要用到多个配置文件,就用这个方法,第一个参数指定了文件的名称。
  • —— 如果只需为 Activity 定义一个配置文件,就用本方法。因为该文件对于 Activity 而言是唯一的,所以不需要命名。

写入数据:

  1. 调用 获得一个
  2. 使用 之类的方法添加数据。
  3. 提交新数据。

读取数据是通过 之类的方法来完成的。

下面给出了一个把计算器的静音模式保存为配置文件的例子:

1 publicclassCalcextendsActivity{ 2     publicstaticfinalString PREFS_NAME ="MyPrefsFile"; 3  4     @Override 5     protectedvoid onCreate(Bundle state){ 6        super.onCreate(state); 7        ... 8  9        // 恢复配置10        SharedPreferences settings = getSharedPreferences(PREFS_NAME,0);11        boolean silent = settings.getBoolean("silentMode",false);12        setSilent(silent);13     }14 15     @Override16     protectedvoid onStop(){17        super.onStop();18 19       // 需要一个 Editor 对象来修改配置。20       // 所有对象都来自于 android.context.Context21       SharedPreferences settings = getSharedPreferences(PREFS_NAME,0);22       SharedPreferences.Editor editor = settings.edit();23       editor.putBoolean("silentMode", mSilentMode);24 25       // 提交修改内容26       editor.commit();27     }28 }

使用内部存储


文件是可以直接保存在内部存储中的。 默认情况下,保存在内部存储中的文件是应用程序的私有数据,其他应用程序是无法访问的(其他用户也不可以)。 当用户卸载该应用时,这些文件将会被删除。

请按照以下步骤在内部存储中创建并写入私有文件:

  1. 调用 ,参数为文件名和操作模式。返回值是一个 对象。
  2. 写入文件。
  3. 关闭流。

示例:

1 String FILENAME ="hello_file";2 Stringstring="hello world!";3 4 FileOutputStream fos = openFileOutput(FILENAME,Context.MODE_PRIVATE);5 fos.write(string.getBytes());6 fos.close();

模式将创建文件(或替换同名文件) 并使其成为应用程序的私有数据。 其他可用的模式还有:

从内部存储中读取文件:

  1. 调用 ,参数为要读取的文件名称。返回值为一个 对象。
  2. 从文件中读取若干字节。
  3. 关闭流。

提示: 如果在编译时就需要保存静态文件,请存放到项目的 res/raw/ 目录下。 可以用 打开这些文件,参数是 R.raw.<filename> 的资源 ID 。返回值是一个 对象,可用它来读取文件(但是无法在原始文件中写入数据)。

保存缓存文件

如果某些数据不需要持久保存,而只是临时缓存一下,请使用 打开一个 即可,此目录是应用程序保存临时文件的内部目录。

如果设备的内部存储空间不足, Android 可能会删除这些缓存文件以释放空间。 不过,请不要依赖系统来清理这些临时文件。而是应该自己管理好缓存文件,使得它们仅占用必需的空间即可,比如 1MB。 当用户卸载应用时,这些文件将会被删除。

其他常用方法

获取内部文件的绝对路径
在内部存储中创建(或打开已有)目录。
删除内部存储中的文件。
返回应用已保存的文件列表数组。

使用外部存储


所有 Android 设备都支持可用于保存文件的共享“外部存储”。 这可以是可卸载的存储介质(比如 SD 卡),也可以是内置(不可卸载的)存储。 保存在外部存储上的文件是全局可读(world-readable)的,并且在启用 USB 存储模式(USB mass storage)与电脑传输文件时可以被修改。

警告: 当用户将外部存储挂接到电脑上,或者介质被卸载时,外部存储就会成为不可用状态,并且无法在外部存储文件上施加任何安全保护措施。 所有应用程序均可读写外部存储中的文件,用户也可以随时将它们删除。

获得外部存储的访问权限

读写外部存储必须申请 权限。例如:

...

如果既要读取又要写入文件,则只需申请 权限即可,因为它同时隐含了读取权限请求。

注意: 自 Android 4.4 开始,如果只是读写应用程序私有的文件,则不再需要申请上述权限了。 详情请参阅后续章节 。

检查存储介质的可用性

在使用外部存储之前,请务必调用 来检查介质的可用性。 存储介质可能是被挂接到电脑上了、已被移除、处于只读状态,或是其他状况。 以下给出了两个可用于检查介质可用性的方法示例:

1 /* 检查外部存储是否可读写 */ 2 publicboolean isExternalStorageWritable(){ 3     String state =Environment.getExternalStorageState(); 4     if(Environment.MEDIA_MOUNTED.equals(state)){ 5         returntrue; 6     } 7     returnfalse; 8 } 9 10 /* 检查外部存储是否至少是可读的 */11 publicboolean isExternalStorageReadable(){12     String state =Environment.getExternalStorageState();13     if(Environment.MEDIA_MOUNTED.equals(state)||14         Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){15         returntrue;16     }17     returnfalse;18 }

方法返回的状态还包括其他类型,比如是否处于共享状态(连接到电脑上)、已被移除、未能正常卸载等等。 当应用程序需要访问存储介质时,可以利用这些状态来把详细信息告知用户。

保存可共享文件

通常,用户创建的文件应该保存在设备的“公共”区域,这是其他应用程序可以访问的区域,用户也很容易从设备上拷走这些文件。 可以使用公共的目录,比如 Music/Pictures/Ringtones/

调用 可以获取一个代表公共目录的 ,参数是目录的类型,比如 等等。只要将文件保存到合适的目录中,系统的 Media Scanner 就可以对它们进行正确归类(比如, 铃声文件就会出现在系统设置的铃声列表中,而不会被视为音乐文件)。

比如,以下给出了在公共的图片目录下新建一个相册目录的示例:

1 publicFile getAlbumStorageDir(String albumName){2     // 获得用户公共图片目录3     File file =newFile(Environment.getExternalStoragePublicDirectory(4             Environment.DIRECTORY_PICTURES), albumName);5     if(!file.mkdirs()){6         Log.e(LOG_TAG,"Directory not created");7     }8     return file;9 }

 

保存应用程序私有的文件

如果文件不会给其他应用程序使用(比如仅供本应用使用的图形纹理或声效文件),请使用外部存储中的私有存储目录,调用 即可。该方法也有一个指定目录类型的 type 参数(如 )。如果目录不需要指定多媒体类型,传入 null 即可返回应用程序私有目录的根目录。

自 Android 4.4 开始,读写应用程序私有目录不再需要申请 权限了。因此可以仅当处于低版本 Android 时才声明这两个权限请求,这通过添加 属性即可实现:

...

注意: 当用户卸载应用程序时,该私有目录及其中的内容都将会被删除。 并且该目录下的文件不会被系统的 Media Scanner 读取,也就不会被 Content Provider 访问到。因此,请勿在私有目录中存放用户的多媒体文件,比如通过本应用拍摄或编辑的照片、通过本应用购买的音乐等, 这些文件都应该。

有时,某些设备会申请一块内部存储区域作为外部存储来使用,且被视为一张 SD 卡。 这种设备如果运行 Android 4.3 及以下版本时, 方法只会访问内部存储上的分区,应用程序就无法读写 SD 卡了。 不过,自 Android 4.4 开始, 对这两块区域都可以访问到,并会返回包含两块存储内容的 数组。数组的第一个成员为外部存储中的文件,只要空间充足且可用,一般应该使用这个区域。 如果想在 Android 4.3 以下版本中也能同时访问这两个区域,请使用 的静态方法 。它也会返回一个 数组,但在 Android 4.3 以下版本时此结果数组中只会包含一个成员。

警告: 虽然由 得到的目录无法被 Content Provider 访问,但拥有 权限的其他应用是可以访问外部存储中的所有文件的,当然也包括这两个目录。 如果需要完全控制对文件的访问,请把文件写入。

保存缓存文件

调用 ,可以打开存放缓存文件的外部存储目录 。 当用户卸载应用程序时,这些文件都将被自动删除。

类似于上面的 ,可以通过 访问到两种外部存储(如果可用的话)中的缓存目录。

提示: 为了节省空间及维持程序性能,在应用程序的整个生命周期中,都应该对缓存文件进行很好地管理,及时删除无用文件。

使用数据库


Android 实现了对 数据库的 数据库的完整支持。 应用程序中的所有类都可以按照名称访问本应用创建的数据库,但其他应用程序则无法访问。

推荐通过新建 方法,以便执行建立数据表的 SQLite 命令。例如:

1 publicn>classDictionaryOpenHelperextendsSQLiteOpenHelper{ 2  3     privatestaticfinalint DATABASE_VERSION =2; 4     privatestaticfinalString DICTIONARY_TABLE_NAME ="dictionary"; 5     privatestaticfinalString DICTIONARY_TABLE_CREATE = 6                 "CREATE TABLE "+ DICTIONARY_TABLE_NAME +" ("+ 7                 KEY_WORD +" TEXT, "+ 8                 KEY_DEFINITION +" TEXT);"; 9 10     DictionaryOpenHelper(Context context){11         super(context, DATABASE_NAME,null, DATABASE_VERSION);12     }13 14     @Override15     publicvoid onCreate(SQLiteDatabase db){16         db.execSQL(DICTIONARY_TABLE_CREATE);17     }18 }

然后,可以获得一个包含上述构造方法的 实例,根据对数据库的读写需求分别调用其 方法。这两个方法都返回代表数据库的 对象,其中包含了一些 SQLite 操作的方法。

通过 方法,可以执行 SQLite 查询。该方法可以传入各种查询参数,比如表名、projection、Select 语句、字段名、分组等等。 如果要进行复杂的查询,比如用到了字段别名,请使用

每个 SQLite 查询都会返回一个 ,它指向所有符合查询条件的记录。 是遍历数据库查询结果并读取行列数据的唯一方式。

在 Android 中使用 SQLite 数据库的应用示例,请参阅 和 。

数据库调试

Android SDK 中包含了一个 sqlite3 数据库工 数据库工具,可以用来浏览数据表、运行 SQL 命令及执行其他 SQLite 数据库维护工作。 关于此工具的使用方法,请参阅

使用网络连接


在网络可用时,可以通过网络在自建的 Web 端服务中保存和读取数据。 有关网络的操作,请使用下列包中的类:

转载地址:http://jpufz.baihongyu.com/

你可能感兴趣的文章
mysqlreport分析工具详解
查看>>
MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
查看>>
Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
查看>>
mysql_real_connect 参数注意
查看>>
mysql_secure_installation初始化数据库报Access denied
查看>>
MySQL_西安11月销售昨日未上架的产品_20161212
查看>>
Mysql——深入浅出InnoDB底层原理
查看>>
MySQL“被动”性能优化汇总
查看>>
MySQL、HBase 和 Elasticsearch:特点与区别详解
查看>>
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>
MySQL不同字符集及排序规则详解:业务场景下的最佳选
查看>>
Mysql不同官方版本对比
查看>>