67.Android中的数据存储总结
本篇文章会帮助大家快速了解Android中各种数据存储机制的应用场景以及基本使用方法,力求在头脑中建立一个“目录”。有了这个目录,具体使用细节在实际应用时再查询文档即可得到。
0. 概述
Android为我们提供了以下存储机制:
Shared Preferences: 以键-值对方式存储应用私有的原始类型数据。
Internal Storage(内部存储): 存储应用私有数据于设备本身的存储空间中
External Storage(外部存储): 将公共数据存储于外部存储(如SD卡)中
SQLite Databases(SQLite数据库): 将结构化数据存储于私有数据库中
Network Connection: 将数据存储在你的网络服务器中
在以上几种数据存储方式中,我们可以根据实际需求进行灵活选择。比如,“数据是本应用私有的还是与其他应用共享”、“要存储的数据大概需要多少存储空间”等都是我们在选择具体的数据存储机制时所要考虑的问题。下面我们来一起看一下这几种存储机制的应用场景和基本使用方法。
1. 使用Shared Preferences
这种存储方式用于存储原始类型数据,包括boolean、int、long、float、double、String等。具体的存储方式是键-值对,若我们不主动删除,这些数据会一直存在。
根据以上介绍,我们很容易得出Shared Preferences适合存储的数据有:
小游戏的历史最高分(整型数据);
用户偏好设置:是否只在wifi时才加载图片(boolean型)、是否开启夜间模式(boolean型);
所有能够用原始类型所表示的用户数据...
要使用Shared Preferences,我们首先要获取一个SharedPreference对象,要获取这个对象有两种方法:
getSharedPreferences()- :使用这个方法可以为每个数据文件指定一个文件名。getPreferences()-当你的Activity只需要一个数据文件来保存用户数据时,这个方法就是你的菜。
在通过以上两种方式之一获取到一个SharedPreferences对象后,我们就可以开始向其中写如用户数据了,具体步骤如下:
调用edit()方法获得一个SharedPreferences.Editor对象
通过
putBoolean(),putDouble()方法向其中添加键-值对调用commit()进行提交
只需三步,我们就成功地把用户数据存起来啦。那么当我们想再此获取已保存的数据时,该怎么做呢?很简单:只需要得到一个SharedPreferences后调用 getBoolean(),getBoolean()等方法即可。
我们来看一下来自Android Developer的示例代码:
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
//从preferences文件中读取之前我们保存的数据
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
@Override
protected void onStop(){
super.onStop();
// 保存用户数据
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// 提交后对用户数据的保存才生效
editor.commit();
}
}
2. 使用内部存储
使用这种方式会把数据存到应用私有的存储空间中,其他应用无权访问这个存储空间,并且当用户卸载你的应用时,这些数据也会被删除掉。由此我们可以知道当我们要保存的数据只用于本应用时,并且希望它同本应用“同生共死”时,就可以使用内部存储。
要创建一个应用私有文件用于数据保存也只需要三步:
调用
openFileOutput()得到一个FileOutputStream(文件输出流)对象使用write()向其中写入数据
调用write()关闭之前打开的文件输出流
示例如下:
String FILENAME = "hello_file";
String string = "hello world!"; FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
上面方法中的MODE_PRIVATE 参数的意思就是这个数据文件是本应用私有的,其他应用不可以访问。
要从内部存储的文件中读取数据也很简单,只需三步:
调用并提供给它我们要读取的文件的名称,它会返回给我们一个
FileInputStream对象使用read()方法从中读取数据
调用close()方法关闭之前打开的文件输入流
有些时候我们想要存储一些临时数据在应用的私有存储空间中,这时候我们可以通过 getCacheDir()方法得到应用用于保存临时缓存文件的内部目录。存储在这个目录下的文件有个特点:当内部存储空间不足时,系统会自动删除一些这个文件夹下的文件。当然,刚靠谱的方式是我们自己维护这个文件夹下的文件。同样,这个文件夹下的文件在应用被卸载时候也会被删除。
关于使用内部存储更详细的介绍请参考文末”参考资料“部分给出的链接。
3. 使用外部存储
Android中的外部存储通常指SD卡,存储于外部存储的文件通常对于各个应用来说是共享的。显然,当我们希望保存的数据被系统中的各个应用共享时,就可以考虑使用外部存储;另一方面,由于手机的内部存储普遍较外部存储小,我们也应该把一些比较大的数据文件放于外部存储中。存储于外部存储中的数据文件不会随着应用的卸载而被删除。
要读写外部存储中的文件,我们首先需要在AndroidManifest.xml文件中声明如下权限:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
这样既可以了吗?显然不行,我们在使用外部存储前首先要确保用户的手机中存在可用的外部存储(万一用户的手机里压根没有SD卡呢...)。实现这个很简单,请看官方给出的示例代码:
/* 检查是否可以读写外部存储 */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
} /* 检查是否只能够读而不能写外部存储 */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
对于一些公共的音乐、图片或是铃声文件,我们可以将它们分别存储于外部存储的 Music/, Pictures/,Ringtones/文件夹中。要得到代表上述公共文件夹的File对象,只需调用getExternalStoragePublicDirectory()方法,并传入一个参数指明我们具体想访问哪个文件夹(DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES等)。
比如下面的方法在公共图片目录中创建了一个用于保存新相册的文件夹:
public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
那么当我们仅仅是因为手机内部存储不足而把数据存于外部存储,有没有办法让这些数据是本应用私有的呢?答案是肯定的。我们只需调用getExternalFilesDir()方法来获取一个外部存储中的私有存储目录。位于这个目录中的数据文件会随着应用的卸载而被删除,毕竟它们只对该应用本身有意义。
从Android 4.4(API 19)开始,读写这个位于外部存储中的应用私有目录无需加上权限声明。所以我们可以在AndroidManifest.xml中添加maxSdkVersion 属性来说明这一权限只在Android 4.4之前才需要。
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest>
同内部存储一样,外部存储中也有个专门用来保存临时文件的缓存文件夹。要获取代表本应用的缓存文件夹的File对象,只需调用getExternalCacheDir()方法,当用户卸载引用时,这些文件也会被自动删除。
4. 使用SQLite数据库
前面我们提到过,SQLite数据库用来存储结构化数据,所谓机构化数据就是有着固定结构的数据。比如成绩表、工资表等等就是天然的适合用数据库存储的结构化数据。
Android推荐的访问SQLite数据库的方式是创建一个SQLiteOpenHelper的子类并重写 onCreate()方法,在这个方法中执行创建数据库表的SQLite命令,比如以下代码:
public class DictionaryOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DICTIONARY_TABLE_NAME = "dictionary";
private static final String DICTIONARY_TABLE_CREATE =
"CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
KEY_WORD + " TEXT, " +
KEY_DEFINITION + " TEXT);";
DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DICTIONARY_TABLE_CREATE);
}
}
然后我们就可以获取以上 SQLiteOpenHelper子类的实例开始对数据库进行操作了。我们可以分别调用 getReadableDatabase()和getWritableDatabase()方法来对数据库进行读操作和写操作。这俩方法都会返回一个 SQLiteDatabase 对象,这个对象提供了查改增删等数据库常规操作方法。
要对SQLite数据库执行查询操作,可以调用 SQLiteDatabase query() 方法。对于复杂查询操作,则使用SQLiteQueryBuilder是个更好的选择。
每个SQLite查询操作都会返回一个指向了“符合查询条件的所有行"的Cursor对象。关于Android中使用SQLite更加详细的介绍,大家可以参考文末给出的链接。
5. 参考资料
Android Developer: https://developer.android.com/guide/topics/data/data-storage.html(墙内用户请看这里:http://hukai.me/android-training-course-in-chinese/basics/data-storage/index.html)
Android中SQLite的使用:http://www.cnblogs.com/Excellent/archive/2011/11/19/2254888.html
67.Android中的数据存储总结的更多相关文章
- Android中的数据存储
Android中的数据存储主要分为三种基本方法: 1.利用shared preferences存储一些轻量级的键值对数据. 2.传统文件系统. 3.利用SQLite的数据库管理系统. 对SharedP ...
- Android中的数据存储(二):文件存储 2017-05-25 08:16 35人阅读 评论(0) 收藏
文件存储 这是本人(菜鸟)学习android数据存储时接触的有关文件存储的知识以及本人自己写的简单地demo,为初学者学习和使用文件存储提供一些帮助.. 如果有需要查看SharedPreference ...
- Android中的数据存储(一):SharedPreferences 2017-05-24 10:35 64人阅读 评论(1) 收藏
SharedPreferences 这是本人(菜鸟)学习android数据存储时接触的有关SharedPreferences的知识以及本人自己写的一个简单地demo,为初学者学习和使用SharedPr ...
- Android笔记(三十八) Android中的数据存储——SharedPreferences
SharedPreferences是Android提供的一种轻型的数据存储方法,其本质是基于xml文件存储的,内部数据以key-value的方式存储,通常用来存储一些简单的配置信息. SharedPr ...
- Android笔记(四十) Android中的数据存储——SQLite(二) insert
准备工作: 我们模拟一个注册的页面,先看UI 我们需要创建一个数据库:user,数据库包含表user,user表包含字段id.username.password.mobilephone MainAct ...
- Android笔记(四十三) Android中的数据存储——SQLite(五)delete
SQLite通过delete()方法删除数据 delete()方法参数说明: delete()方法参数 对应sql部分 描述 table delte from table_name 要删除的表 whe ...
- Android笔记(四十七) Android中的数据存储——XML(三)SAX解析
SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备. SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SA ...
- Android笔记(四十六) Android中的数据存储——XML(二)PULL解析
PULL 的工作原理: XML pull提供了开始元素和结束元素.当某个元素开始时,可以调用parser.nextText()从XML文档中提取所有字符数据.当解析到一个文档结束时,自动生成EndDo ...
- Android笔记(四十五) Android中的数据存储——XML(一)DOM解析器
DOM解析XML在j2ee开发中比较常见,在Dom解析的过程中,是先把dom全部文件读入到内存中,然后使用dom的api遍历所有数据,检索想要的数据,这种方式显然是一种比较消耗内存的方式,对于像手机这 ...
随机推荐
- jquery.validate.min.js 用法方法示例
页面html 代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...
- 单机多实例Tomcat部署
单机单用户基础上, 如何运行多个tomcat实例. 首先是tomcat的目录结构 bin – 包含所有运行tomcat的二进制和脚本文件 lib – 包含tomcat使用的所有共享库 c ...
- mysql新建用户的方法
新增 insert into mysql.user(Host,User,Password,ssl_cipher,x509_issuer,x509_subject) values("local ...
- codevs 2801 LOL-盖伦的蹲草计划
时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题目描述 Description 众所周知,LOL这款伟大的游戏,有个叫盖伦的英雄.他的伟大之处在于他特别喜欢蹲 ...
- 黑暗圣经---物业公司CTO/CEO改如何给老板推荐物业信息化产品
多年前一次偶然的机会进入到物业信息化行业,在这个过程中认识很多奋战在物业一线的技术大牛.很多时候都会介绍一些朋友给我认识一下,帮我推荐一下我们闻风多奇的物业管理平台.很多朋友看完我们的系统之后都会很开 ...
- Hadoop: MapReduce2多个job串行处理
复杂的MapReduce处理中,往往需要将复杂的处理过程,分解成多个简单的Job来执行,第1个Job的输出做为第2个Job的输入,相互之间有一定依赖关系.以上一篇中的求平均数为例,可以分解成三个步骤: ...
- Openwrt iptables分析
这里将载有Openwrt的WR841N的路由表dump出来分析一下. 这个是dump出iptables的命令 root@OpenWrt:/etc/config# iptables-save 这里分为4 ...
- WPF EventSetter Handler Command
最近做一个工具,突然发现ListBox和ListView等列表控件的MouseDoubleClick事件有时候是获取不到当前双击的行对象数据的,比如这样写: <ListBox Grid.Row= ...
- 在CentOS上部署基于dnx/coreclr的ASP.NET 5应用程序
在Ubuntu上写好了一个简单的ASP.NET 5应用程序,尝试将这个程序部署在没有mono环境的CentOS服务器上. 部署步骤如下: 1)安装libuv(KestrelHttpServer需要它) ...
- Koa框架实践与中间件原理剖析
最近尝试用了一下Koa,并在此记录一下使用心得. 注意:本文是以读者已经了解Generator和Promise为前提在写的,因为单单Generator和Promise都能够写一篇博文来讲解介绍了,所 ...