Android Learning:数据存储方案归纳与总结
前言
最近在学习《第一行android代码》和《疯狂android讲义》,我的感触是Android应用的本质其实就是数据的处理,包括数据的接收,存储,处理以及显示,我想针对这几环分别写一篇博客,记得我的学习心得,也希望跟各位新手同学相互努力促进。今天这篇博客,我想介绍一下数据的存储,因为数据的接收,存储,处理以及显示这几环环环相扣,而数据的存储直接关系到数据的处理和显示,所以显得尤为重要。
所以本文针对数据存储的常见方案和其使用进行了归纳。分为程序内存储和程序间数据访问,程序内存储介绍了文件存储、SharedPreferences存储、数据库存储三种不同的存储方式的优缺点以及区别,用用例子详细说明了各自的用法,重点介绍了数据库存储的操作。 程序间数据访问介绍了内容提供器。
Android程序内数据存储方案:
Android系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储、SharedPreferences存储以及数据库存储。当然,除了这三种方式之外,还可以将数据保存在手机的SD卡中,不过使用文件存储、SharedPreferences存储以及数据库存储会相对于将数据保存在手机的SD卡中更安全也更简单一些[1]。
一、文件存储:
文件存储是Android中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据。如果你想使用文件存储的方式来保存一些较为复杂的文本数据,就需要定义一套自己的格式规范,这样方便于之后将数据从文件中重新解析出来。由于文件存储的方式有着起局限性,在实际工程项目中用的很少,我们也就不具体展开说。
二、SharedPreferences存储:
不同于文件的存储方式,SharedPreference是使用键值对的方式来存储数据的。也就是说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且SharedPreferences还支持多种不同的数据类型存储,这就是SharedPreference比文件存储的优越性所在。
三种获取SharedPreferences对象的方法
Context类中的getSharedPreferences()方法
SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
第一个参数用于指定SharedPreferences文件的名称。第二个参数指定操作模式,MODE_PRIVATE表示只有当前的应用程序才可以对这个SharedPreferences进行读写,MODE_MULTI_PROCESS则一般用于会有多个进程中对同一个SharedPreferences文件进行读写的情况。
Activity类中的getPreferences()方法
跟Context类中的getSharedPreferences()方法很相似,不过只接受一个操作模式参数
PreferenceManager类中的getDefaultSharedPreferences()方法
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
这是一个静态方法,接收Context参数。
例子:通过SharedPreferences进行读写数据
shareRead = (Button) findViewById(R.id.share_read);
shareWrite = (Button) findViewById(R.id.share_write);
/**
* pref = PreferenceManager.getDefaultSharedPreferences(this);
*/
pref = getSharedPreferences("data", MODE_PRIVATE);
editor = pref.edit();
shareWrite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editor.putString("write", "This is A String");
/*数据提交*/
editor.commit();
}
});
shareRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str = pref.getString("write", null);
Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
}
});
存储数据(shareWrite)的实现
1. 调用SharedPreferences对象的Edit()方法获取一个SharedPreferences.Editor对象
2. 向SharedPreferences.Editor对象中添加数据,采用putBoolean、putString等方法
3. 调用commint()方法将添加的数据提交
获取数据(shareRead)的实现
1. 直接采用SharedPreferences对象的get方法
2. get方法接收两个参数,第一个是键,第二个参数是默认值,当传入的键找不大到对应的值,返回默认值
效果图
sharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其只能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式[2]。
三、数据库存储
创建数据库: SQLiteDatabase.execSQL()
public class MyDatabaseHelper extends SQLiteOpenHelper {
/*建立一个student的数据表*/
public static final String CREATE_STUDENT = "create table student ("
+ "id integer primary key autoincrement,"
+ "number integer,"
+ "name text,"
+ "major text)"; private Context myContext; public MyDatabaseHelper(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
myContext = context;
} @Override
public void onCreate(SQLiteDatabase db) {
/*创建数据库*/
db.execSQL(CREATE_STUDENT);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
更新数据库:onUpgrade()
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/*drop table if exists student:发现数据库已经存在student这张表就删除*/
db.execSQL("drop table if exists student");
onCreate(db);
}
当表中没有我们所要的数据时:
添加数据:insert(String table, String nullColumnHack, ContentValues values)
MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "student.db, null, 2");
SQLiteDatabase db = dbHelper. getWritableDatabase();
ContentValues values = new ContentValues();
values.put("number", 123456);
values.put("name", "steve");
values.put("major", "CS");
db.insert("student", null, values);
当表中数据已经存在,但是数据需要修改:
更新数据:update(String table, ContentValues values, String whereClause, String[] whereArgs)
db.update("student", values, "name = ?", new String[]{"steve"});
删除数据:delete(String table, String whereClause, String[] whereArgs)
db.delete("student", "name = ?", new String[]{"steve"});
查询数据:
Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy)
Cursor rawQuery(String sql, String[] selectionArgs)
查询表
query()方法参数 | 对应SQL部分 | 描述 |
table | from table_name | 指定查询的表明 |
columns | select column1,column2 | 指定查询的列名 |
selection | where column = value | 指定where的约束条件 |
selectionArgs | - | 为where中的占位符提供具体的值 |
groupBy | group by column | 指定需要group by的列 |
having | having column = value | 对group by后的结果进一步约束 |
orderBy | order by column1, column2 | 指定查询结果的排序方式 |
Cursor cursor = db.query("student", null, "number = ?", new String[] {"123456"}, null, null, null);
到这里,我们可以看到update()、delete()、query()等方法中都传入了String[] whereArgs参数,这是一个字符串数组,也是判断条件,这可以帮助我们在同一个类目中搜索几类关键字的数据
使用事务:事务的特性可以保证让某一系列的操作要么全部完成,要么一个都不会完成
SQLiteDatabase中包含两个方法控制事务:
开始事务:beginTransaction()
结束事务:endTransaction()
是否在事务中:inTransaction()
设置事务标志:setTransactionSuccessful()
表示事物执行成功。如果程序在事务执行中调用该方法设置了事务成功则提交事务,否则程序将会回滚事务。
注意:
数据库查看,我们可以通过命令行方式进入SDK/platform-tools,输入adb shell,即可输入数据库的基本指令。但我觉得这种方式并不是很方便,我的做法是,登录SQLite Expert官方网站(http://www.sqliteexpert.com/download.html)下载一个SQLite Expert Personal 3,个人版的是免费的。然后就可以在Android Studio或者Eclipse中进如Android Monitor Device,在File Explorer中找到data/data/包名/database/*.db,点击导出,然后就可以用这个软件打开。
Android程序间数据内容提供器:
上述三种方案是单个程序数据的存储,而我们在有些场景中,需要用到系统应用的数据,比如使用系统的通讯录、短信和媒体库等功能,那这就需要我们使用内容提供器(Content Provider),它可以用于在不同的应用程序之间实现数据共享。
一、获取其他应用的数据
内容提供器是通过ContentResolver类来访问内容提供器中共享的数据,ContentResolver是由Context.getContentResolver() 得到的。
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder) ;
查询表
query()方法参数 | 对应SQL部分 | 描述 |
uri | from table_name | 指定查询的表明 |
projection | where column = value | 指定where的约束条件 |
selection | - | 为where中的占位符提供具体的值 |
selectionArgs | group by column | 指定需要group by的列 |
orderBy | order by column1, column2 | 指定查询结果的排序方式 |
讲到这里,我们会发现,内容提供器的查询方法跟数据库很类似,使用query()方法,不同的是,传进query()方法的参数有所区别。内容提供器传进query的值包含着URI,而URI记录着目标数据的地址,而数据库传进query的值包含着表名,因为数据库是对自身程序文件目录下进行的操作,所以并不需要定位,而内容提供器首先要定位到程序的包名,进而定位到数据文件夹,最终定位到表名,在URI中,我们可以看到最后一个斜杠后就是表名。
内容URI
URI的标准格式
content://com.example.app.provider/table
URI的解析
Uri uri = Uri.parse("content://com.example.app.provider/table")
URI规则
* 表示匹配任意长度的任意字符
content://com.example.app.provider/*
# 表示匹配任意长度的数字
content://com.example.app.provider/table/#
二、提供应用自身的数据
内容提供器的六个方法
1、onCreate()
初始化内容提供器。完成数据库的创建和升级,只有在ContentResolver尝试访问程序数据才会被初始化
2、query()
查询数据。uri确定查哪张表,projection查询列,selection和selectionArgs查询哪些行
3、insert()
添加数据
4、update()
更新内容提供器已有的数据
5、delete()
删除数据
6、getType()
根据传入的内容URI来返回相应的MIME类型。
一个内容URI对应的MIME字符串只要有三部分组成
(1)必须以vnd开头
(2)以路径结尾,后接android.cursor.dir/,以id结尾,后接android.cursor.item/
(3)最后接上vnd.<authority>.<path>
匹配内容URI
UriMatcher类
addURI()方法,这个方法接受三个参数,分别把权限、路径和一个自定义代码传进去
match()方法,将Uri对象传入,返回值是某个能够匹配这个Uri对象说对应的自定义代码
内容提供类的核心是通过URI对象来定位数据的,但数据定位成功之后,那么就可以用类似于数据库操作的手段进行读取。如果想共享自身的数据,也可以通过URI对象,抛出自己的位置,等待其他程序定位到自身获取数据
总结:
存储方式 | 用途 | 特点 |
文件存储 | 存储一些简单的文本数据或二进制数据 | 不对存储的内容进行任何的格式化处理 |
SharedPreferences存储 | 存储boolean,int,float,long和String五种简单的数据类型,数据量小 | 方便,简洁,使用键值对的方式来存储数据,支持多种不同的数据类型存储,但不能条件查询 |
数据库存储 | 数据量大,且有条件 | 功能强大,条件查询,数据的增删改查,但使用较为复杂 |
内容提供器 | 跨程序之间的数据交换 | 通过URI对象来定位数据源 |
[1] 郭霖. 第一行代码 Android[J]. 2014.
[2] 大气象.Android四种存储方式.http://www.cnblogs.com/greatverve/archive/2011/12/27/android-sharedpreference-file-SQlite-contentprovider.html
Android Learning:数据存储方案归纳与总结的更多相关文章
- Android实现数据存储技术
转载:Android实现数据存储技术 本文介绍Android中的5种数据存储方式. 数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用Shar ...
- 关于Android开发数据存储的方式(一)
关于Android开发数据存储方式(一) 在厦门做Android开发也有两个月了,快情人节了.我还在弄代码. 在微信平台上开发自己的APP,用到了数据存储的知识,如今总结一下: 整体的来讲.数据存储方 ...
- Android本地数据存储: ASimpleCache
一:前言 在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储.昨天并没有仔细的对比Re ...
- Android中数据存储(一)
国庆没有给国家添堵,没有勾搭妹子,乖乖的写着自己的博客..... 本文将为大家介绍Android中数据存储的五种方式,数据存储可是非常重要的知识哦. 一,文件存储数据 ①在ROM存储数据 关于在ROM ...
- Android本地数据存储复习
Android本地数据存储复习 Android无论是应用层还是系统层都需要在本地保存一些数据,尤其在应用层中使用的就更为普遍,大体有这么几种:SharedPreference,file,sqlite数 ...
- android学习笔记45——android的数据存储和IO
android的数据存储和IO SharedPreferences与Editor简介 SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此其保存的数据主要是简单的类型的ke ...
- android中数据存储
android中数据存储 Android 中存储数据的方式有五种:SQLite数据库.文件存储.内容提供者.网络.SharedPreferences(Key----value)五种存储方式. ...
- Sqlserver 高并发和大数据存储方案
Sqlserver 高并发和大数据存储方案 随着用户的日益递增,日活和峰值的暴涨,数据库处理性能面临着巨大的挑战.下面分享下对实际10万+峰值的平台的数据库优化方案.与大家一起讨论,互相学习提高! ...
- 前端数据存储方案集合(cookie localStorage等)以及详解 (二)
前端数据存储方案集合(cookie localStorage等)以及详解 (二) 在之前的文章中已经介绍到了 前端存储方案中的 cookie . 但是 cookie 的存储上限是 4KB. 如果超过了 ...
随机推荐
- MyEclipse10搭建Strust2开发环境
一.创建一个JavaWeb项目 启动MyEclipse10 ,然后在MyEclipse中创建一个JavaWeb项目,点击[File]---->[New]---->[WebProjec ...
- 闪回还原点(Flashback Restore Point)
Flashback Restore Point(闪回还原点) 闪回还原点分两种,一种是Normal Restore Points(正常还原点),另一种是Guaranteed Restore Point ...
- mysql in 的两种使用方法
简述MySQL 的in 的两种使用方法: 他们各自是在 in keyword后跟一张表(记录集).以及在in后面加上字符串集. 先讲后面跟着一张表的. 首先阐述三张表的结构: s(sno,sname. ...
- 用NodeJs实现延迟调用,规避定时任务的闭包问题
很多人在用NodeJs的setTimeout(callback, delay[, arg][, ...])编写定时任务时,习惯上直接操作callback外部的对象object(闭包的特点).这样做有一 ...
- 关于weight属性使用的一些细节
之前被这个属性困扰过好久,今天一个偶然的机会,终于把这个搞清楚了,现在与大家分享一下. 假设我们要在一个LinearLayout布局中显示两个按钮,button1和button2,button2的宽度 ...
- eclipse同时开两个tomcat
首先设置环境变量: 接着修改其中一个tomcat下bin文件夹的startup.bat和catalina.bat 将里面所有CATALINA_HOME都修改为CATALINA_HOME2 然后 修改c ...
- PHP-popen() 函数打开进程文件指针
待更新 版权声明:本文为博主原创文章,未经博主允许不得转载.
- ui-router的使用
使用时需要ui中用ui-view指令指定 如: <div ui-view></div> 首先配置注册 ui-route var mainModule = angular.mod ...
- (转)Spring读书笔记-----Spring的Bean之Bean的基本概念
从前面我们知道Spring其实就是一个大型的工厂,而Spring容器中的Bean就是该工厂的产品.对于Spring容器能够生产那些产品,则取决于配置文件中配置. 对于我们而言,我们使用Spring框架 ...
- JAVA SE 框架之俄罗斯方块的效果
Mygame package com.sun.c; import java.awt.event.KeyListener; import com.sun.v.MyJpanel; import com.s ...