数据存储五种方式.docx
《数据存储五种方式.docx》由会员分享,可在线阅读,更多相关《数据存储五种方式.docx(31页珍藏版)》请在冰点文库上搜索。
数据存储五种方式
Andorid五种数据存储方式:
本文介绍Android平台进行数据存储的五大方式,分别如下:
1 使用SharedPreferences存储数据
2 文件存储数据
3 SQLite数据库存储数据
4 使用ContentProvider存储数据
5 网络存储数据
下面详细讲解这五种方式的特点
第一种:
使用SharedPreferences存储数据共享参数
适用范围:
保存少量的数据,且这些数据的格式非常简单:
字符串型、基本类型的值。
比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、小游戏的玩家积分等),解锁口令密码等
核心原理:
保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。
通过DDMS的FileExplorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data//shared_prefs目录下。
SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。
SharedPreferences本身是一个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(Stringname,intmode)方法来获取SharedPreferences实例,该方法中name表示要操作的xml文件名,第二个参数具体如下:
Context.MODE_PRIVATE:
指定该SharedPreferences数据只能被本应用程序读、写。
Context.MODE_WORLD_READABLE:
指定该SharedPreferences数据能被其他应用程序读,但不能写。
Context.MODE_WORLD_WRITEABLE:
指定该SharedPreferences数据能被其他应用程序读,写
Editor有如下主要重要方法:
SharedPreferences.Editorclear():
清空SharedPreferences里所有数据
SharedPreferences.EditorputXxx(Stringkey,xxxvalue):
向SharedPreferences存入指定key对应的数据,其中xxx可以是boolean,float,int等各种基本类型据
SharedPreferences.Editorremove():
删除SharedPreferences中指定key对应的数据项
booleancommit():
当Editor编辑完成后,使用该方法提交修改
实际案例:
运行界面如下
这里只提供了两个按钮和一个输入文本框,布局简单,故在此不给出界面布局文件了,程序核心代码如下:
classViewOclimplementsView.OnClickListener{
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.btnSet:
//步骤1:
获取输入值
Stringcode=txtCode.getText().toString().trim();
//步骤2-1:
创建一个SharedPreferences.Editor接口对象,lock表示要写入的XML文件名,MODE_WORLD_WRITEABLE写操作
SharedPreferences.Editoreditor=getSharedPreferences("lock",MODE_WORLD_WRITEABLE).edit();
//步骤2-2:
将获取过来的值放入文件
editor.putString("code",code);
//步骤3:
提交
mit();
Toast.makeText(getApplicationContext(),"口令设置成功",Toast.LENGTH_LONG).show();
break;
caseR.id.btnGet:
//步骤1:
创建一个SharedPreferences接口对象
SharedPreferencesread=getSharedPreferences("lock",MODE_WORLD_READABLE);
//步骤2:
获取文件中的值
Stringvalue=read.getString("code","");
Toast.makeText(getApplicationContext(),"口令为:
"+value,Toast.LENGTH_LONG).show();
break;
}
}
}
读写其他应用的SharedPreferences:
步骤如下
1、在创建SharedPreferences时,指定MODE_WORLD_READABLE模式,表明该SharedPreferences数据可以被其他程序读取
2、创建其他应用程序对应的Context:
ContextpvCount=createPackageContext("com.tony.app",Context.CONTEXT_IGNORE_SECURITY);这里的com.tony.app就是其他程序的包名
3、使用其他程序的Context获取对应的SharedPreferences
SharedPreferencesread=pvCount.getSharedPreferences("lock",Context.MODE_WORLD_READABLE);
4、如果是写入数据,使用Editor接口即可,所有其他操作均和前面一致。
SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。
但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。
所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。
第二种:
文件存储数据SD卡
核心原理:
Context提供了两个方法来打开数据文件里的文件IO流FileInputStreamopenFileInput(Stringname);FileOutputStream(Stringname,intmode),这两个方法第一个参数用于指定文件名,第二个参数指定打开文件的模式。
具体有以下值可选:
MODE_PRIVATE:
为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。
可 以使用Context.MODE_APPEND
MODE_APPEND:
模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
MODE_WORLD_READABLE:
表示当前文件可以被其他应用读取;
MODE_WORLD_WRITEABLE:
表示当前文件可以被其他应用写入。
除此之外,Context还提供了如下几个重要的方法:
getDir(Stringname,intmode):
在应用程序的数据文件夹下获取或者创建name对应的子目录
FilegetFilesDir():
获取该应用程序的数据文件夹得绝对路径
String[]fileList():
返回该应用数据文件夹的全部文件
实际案例:
界面沿用上图
核心代码如下:
publicStringread(){
try{
FileInputStreaminStream=this.openFileInput("message.txt");
byte[]buffer=newbyte[1024];
inthasRead=0;
StringBuildersb=newStringBuilder();
while((hasRead=inStream.read(buffer))!
=-1){
sb.append(newString(buffer,0,hasRead));
}
inStream.close();
returnsb.toString();
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
publicvoidwrite(Stringmsg){
//步骤1:
获取输入值
if(msg==null)return;
try{
//步骤2:
创建一个FileOutputStream对象,MODE_APPEND追加模式
FileOutputStreamfos=openFileOutput("message.txt",
MODE_APPEND);
//步骤3:
将获取过来的值放入文件
fos.write(msg.getBytes());
//步骤4:
关闭数据流
fos.close();
}catch(Exceptione){
e.printStackTrace();
}
}
openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/”,如果文件不存在,Android会自动创建它。
创建的文件保存在/data/data//files目录,如:
/data/data/cn.tony.app/files/message.txt,
下面讲解某些特殊文件读写需要注意的地方:
读写sdcard上的文件
其中读写步骤按如下进行:
1、调用Environment的getExternalStorageState()方法判断手机上是否插了sd卡,且应用程序具有读写SD卡的权限,如下代码将返回true
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
2、调用Environment.getExternalStorageDirectory()方法来获取外部存储器,也就是SD卡的目录,或者使用"/mnt/sdcard/"目录
3、使用IO流操作SD卡上的文件
注意点:
手机应该已插入SD卡,对于模拟器而言,可通过mksdcard命令来创建虚拟存储卡
必须在AndroidManifest.xml上配置读写SD卡的权限
name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
name="android.permission.WRITE_EXTERNAL_STORAGE"/>
案例代码:
//文件写操作函数
privatevoidwrite(Stringcontent){
if(Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)){//如果sdcard存在
Filefile=newFile(Environment.getExternalStorageDirectory()
.toString()
+File.separator
+DIR
+File.separator
+FILENAME);//定义File类对象
if(!
file.getParentFile().exists()){//父文件夹不存在
file.getParentFile().mkdirs();//创建文件夹
}
PrintStreamout=null;//打印流对象用于输出
try{
out=newPrintStream(newFileOutputStream(file,true));//追加文件
out.println(content);
}catch(Exceptione){
e.printStackTrace();
}finally{
if(out!
=null){
out.close();//关闭打印流
}
}
}else{//SDCard不存在,使用Toast提示用户
Toast.makeText(this,"保存失败,SD卡不存在!
",Toast.LENGTH_LONG).show();
}
}
//文件读操作函数
privateStringread(){
if(Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)){//如果sdcard存在
Filefile=newFile(Environment.getExternalStorageDirectory()
.toString()
+File.separator
+DIR
+File.separator
+FILENAME);//定义File类对象
if(!
file.getParentFile().exists()){//父文件夹不存在
file.getParentFile().mkdirs();//创建文件夹
}
Scannerscan=null;//扫描输入
StringBuildersb=newStringBuilder();
try{
scan=newScanner(newFileInputStream(file));//实例化Scanner
while(scan.hasNext()){//循环读取
sb.append(scan.next()+"\n");//设置文本
}
returnsb.toString();
}catch(Exceptione){
e.printStackTrace();
}finally{
if(scan!
=null){
scan.close();//关闭打印流
}
}
}else{//SDCard不存在,使用Toast提示用户
Toast.makeText(this,"读取失败,SD卡不存在!
",Toast.LENGTH_LONG).show();
}
returnnull;
}
第三种:
SQLite存储数据{}
SQLite是轻量级嵌入式数据库引擎,它支持SQL语言,并且只利用很少的内存就有很好的性能。
现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧
SQLiteDatabase类为我们提供了很多种方法,上面的代码中基本上囊括了大部分的数据库操作;对于添加、更新和删除来说,我们都可以使用
1db.executeSQL(Stringsql);
2db.executeSQL(Stringsql,Object[]bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集
除了统一的形式之外,他们还有各自的操作方法:
1db.insert(Stringtable,StringnullColumnHack,ContentValuesvalues);
2db.update(Stringtable,Contentvaluesvalues,StringwhereClause,StringwhereArgs);
3db.delete(Stringtable,StringwhereClause,StringwhereArgs);
以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age>?
andage
”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样
下面给出demo
数据的添加
1.使用insert方法
1ContentValuescv=newContentValues();//实例化一个ContentValues用来装载待插入的数据
2cv.put("title","youarebeautiful");//添加title
3cv.put("weather","sun");//添加weather
4cv.put("context","xxxx");//添加context
5Stringpublish=newSimpleDateFormat("yyyy-MM-ddHH:
mm:
ss")
6.format(newDate());
7cv.put("publish",publish);//添加publish
8db.insert("diary",null,cv);//执行插入操作
2.使用execSQL方式来实现
Stringsql="insertintouser(username,password)values('JackJohnson','iLovePopMuisc');//插入操作的SQL语句
db.execSQL(sql);//执行SQL语句
数据的删除
同样有2种方式可以实现
StringwhereClause="username=?
";//删除的条件
String[]whereArgs={"JackJohnson"};//删除的条件参数
db.delete("user",whereClause,whereArgs);//执行删除
使用execSQL方式的实现
Stringsql="deletefromuserwhereusername='JackJohnson'";//删除操作的SQL语句
db.execSQL(sql);//执行删除操作
数据修改
同上,仍是2种方式
ContentValuescv=newContentValues();//实例化ContentValues
cv.put("password","iHatePopMusic");//添加要更改的字段及内容
StringwhereClause="username=?
";//修改条件
String[]whereArgs={"JackJohnson"};//修改条件的参数
db.update("user",cv,whereClause,whereArgs);//执行修改
使用execSQL方式的实现
Stringsql="updateusersetpassword='iHatePopMusic'whereusername='JackJohnson'";//修改的SQL语句
db.execSQL(sql);//执行修改
数据查询
下面来说说查询操作。
查询操作相对于上面的几种操作要复杂些,因为我们经常要面对着各种各样的查询条件,所以系统也考虑到这种复杂性,为我们提供了较为丰富的查询形式:
1db.rawQuery(Stringsql,String[]selectionArgs);
2db.query(Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy);
3db.query(Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy,Stringlimit);
4db.query(Stringdistinct,Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy,Stringlimit);
上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;
各参数说明:
∙table:
表名称
∙colums:
表示要查询的列所有名称集
∙selection:
表示WHERE之后的条件语句,可以使用占位符
∙selectionArgs:
条件语句的参数数组
∙groupBy:
指定分组的列名
∙having:
指定分组条件,配合groupBy使用
∙orderBy:
y指定排序的列名
∙limit:
指定分页参数
∙distinct:
指定“true”或“false”表示要不要过滤重复值
∙Cursor:
返回值,相当于结果集R