当前位置: 移动技术网 > IT编程>移动开发>Android > 5种Android数据存储方式汇总

5种Android数据存储方式汇总

2019年07月24日  | 移动技术网IT编程  | 我要评论

冯一非图片,三级电影下载,bigbang胜利女友

本文介绍android中的5种数据存储方式。

数据存储在开发中是使用最频繁的,在这里主要介绍android平台中实现数据存储的5种方式,分别是:

1 使用sharedpreferences存储数据
2 文件存储数据
3 sqlite数据库存储数据
4 使用contentprovider存储数据
5 网络存储数据

下面将为大家一一详细介绍。

第一种:使用sharedpreferences存储数据
sharedpreferences是android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在activity中 重载窗口状态onsaveinstancestate保存一般使用sharedpreferences完成,它提供了android平台常规的long长 整形、int整形、string字符串型的保存。

它是什么样的处理方式呢? sharedpreferences类似过去windows系统上的ini配置文件,但是它分为多种权限,可以全局共享访问,android123提示最终是以xml方式来保存,整体效率来看不是特别的高,对于常规的轻量级而言比sqlite要好不少,如果真的存储量不大可以考虑自己定义文件格式。xml 处理时dalvik会通过自带底层的本地xml parser解析,比如xmlpull方式,这样对于内存资源占用比较好。

它的本质是基于xml文件存储key-value键值对数据,通常用来存储一些简单的配置信息。
其存储位置在/data/data/< >/shared_prefs目录下。
sharedpreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过editor对象实现。

实现sharedpreferences存储的步骤如下:
step1、根据context获取sharedpreferences对象
step2、利用edit()方法获取editor对象。
step3、通过editor对象存储key-value键值对数据。
step4、通过commit()方法提交数据。

下面是示例代码:

public class mainactivity extends activity {  
 @override
   public void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.main);

    //获取sharedpreferences对象
    context ctx = mainactivity.this;    
    sharedpreferences sp = ctx.getsharedpreferences("sp", mode_private);
    //存入数据
    editor editor = sp.edit();
    editor.putstring("string_key", "string");
    editor.putint("int_key", 0);
    editor.putboolean("boolean_key", true);
    editor.commit();

    //返回string_key的值
    log.d("sp", sp.getstring("string_key", "none"));
    //如果not_exist不存在,则返回值为"none"
    log.d("sp", sp.getstring("not_exist", "none"));
   }

} 

这段代码执行过后,即在/data/data/com.test/shared_prefs目录下生成了一个sp.xml文件,一个应用可以创建多个这样的xml文件。

sharedpreferences对象与sqlite数据库相比,免去了创建数据库,创建表,写sql语句等诸多操作,相对而言更加方便,简洁。但是sharedpreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和string五种简单的数据类型,比如其无法进行条件查询等。所以不论sharedpreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如sqlite数据库这样的其他数据存储方式。

第二种:文件存储数据
关于文件存储,activity提供了openfileoutput()方法可以用于把数据输出到文件中,具体的实现过程与在j2se环境中保存数据到文件中是一样的。
文件可用来存放大量数据,如文本、图片、音频等。
默认位置:/data/data/< >/files/.。

代码示例:

public void save()
 {

    try {
      fileoutputstream outstream=this.openfileoutput("a.txt",context.mode_world_readable);
      outstream.write(text.gettext().tostring().getbytes());
      outstream.close();
      toast.maketext(myactivity.this,"saved",toast.length_long).show();
    } catch (filenotfoundexception e) {
      return;
    }
    catch (ioexception e){
      return ;
    }

 } 

openfileoutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,android 会自动创建它。
创建的文件保存在/data/data//files目录,如: /data/data/cn.itcast.action/files/itcast.txt ,通过点击eclipse菜单“window”-“show view”-“other”,在对话窗口中展开android文件夹,选择下面的file explorer视图,然后在file explorer视图中展开/data/data//files目录就可以看到该文件。

openfileoutput()方法的第二参数用于指定操作模式,有四种模式,分别为:

context.mode_private = 0
context.mode_append = 32768
context.mode_world_readable = 1
context.mode_world_writeable = 2

context.mode_private:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用context.mode_append
context.mode_append:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
context.mode_world_readable和context.mode_world_writeable用来控制其他应用是否有权限读写该文件。
mode_world_readable:表示当前文件可以被其他应用读取;
mode_world_writeable:表示当前文件可以被其他应用写入。

如果希望文件被其他应用读和写,可以传入: openfileoutput(“itcast.txt”, context.mode_world_readable + context.mode_world_writeable); android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data//files),其他程序无法访问。
除非在创建时指定了context.mode_world_readable或者context.mode_world_writeable ,只有这样其他程序才能正确访问。

读取文件示例:

public void load()
{
  try {
    fileinputstream instream=this.openfileinput("a.txt");
    bytearrayoutputstream stream=new bytearrayoutputstream();
    byte[] buffer=new byte[1024];
    int length=-1;
while((length=instream.read(buffer))!=-1)  {
      stream.write(buffer,0,length);
    }

    stream.close();
    instream.close();
    text.settext(stream.tostring());
    toast.maketext(myactivity.this,"loaded",toast.length_long).show();
  } catch (filenotfoundexception e) {
    e.printstacktrace();
  }
  catch (ioexception e){
    return ;
  }

} 

对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定context.mode_world_readable和context.mode_world_writeable权限。

activity还提供了getcachedir()和getfilesdir()方法: getcachedir()方法用于获取/data/data//cache目录 getfilesdir()方法用于获取/data/data//files目录。

把文件存入sdcard:
使用activity的openfileoutput()方法保存文件,文件是存放在手机空间上,一般手机的存储空间不是很大,存放些小文件还行,如果要存放像视频这样的大文件,是不可行的。对于像视频这样的大文件,我们可以把它存放在sdcard。
sdcard是干什么的?你可以把它看作是移动硬盘或u盘。 在模拟器中使用sdcard,你需要先创建一张sdcard卡(当然不是真的sdcard,只是镜像文件)。

创建sdcard可以在eclipse创建模拟器时随同创建,也可以使用dos命令进行创建,如下: 在dos窗口中进入android sdk安装路径的tools目录,输入以下命令创建一张容量为2g的sdcard,文件后缀可以随便取,建议使用.img: mksdcard 2048m d:\androidtool\sdcard.img 在程序中访问sdcard,你需要申请访问sdcard的权限。

在androidmanifest.xml中加入访问sdcard的权限如下:

 <!-- 在sdcard中创建与删除文件权限 -->
  <uses-permission android:name="android.permission.mount_unmount_filesystems"/>

  <!-- 往sdcard写入数据权限 -->
  <uses-permission android:name="android.permission.write_external_storage"/> 

要往sdcard存放文件,程序必须先判断手机是否装有sdcard,并且可以进行读写。
注意:访问sdcard必须在androidmanifest.xml中加入访问sdcard的权限。

 if(environment.getexternalstoragestate().equals(environment.media_mounted)){ 
file sdcarddir = environment.getexternalstoragedirectory();//获取sdcard目录     

file savefile = new file(sdcarddir, “a.txt”);
    fileoutputstream outstream = new fileoutputstream(savefile);
    outstream.write("test".getbytes());
    outstream.close();
}

​environment.getexternalstoragestate()方法用于获取sdcard的状态,如果手机装有sdcard,并且可以进行读写,那么方法返回的状态等于environment.media_mounted。
environment.getexternalstoragedirectory()方法用于获取sdcard的目录,当然要获取sdcard的目录,你也可以这样写:

file sdcarddir = new file("/sdcard"); //获取sdcard目录
file savefile = new file(sdcarddir, "itcast.txt");
//上面两句代码可以合成一句:
file savefile = new file("/sdcard/a.txt");
fileoutputstream outstream = new fileoutputstream(savefile);
outstream.write("test".getbytes());
outstream.close();

第三种:sqlite数据库存储数据

sqlite是轻量级嵌入式数据库引擎,它支持 sql 语言,并且只利用很少的内存就有很好的性能。此外它还是开源的,任何人都可以使用它。许多开源项目((mozilla, php, python)都使用了 sqlite.sqlite 由以下几个组件组成:sql 编译器、内核、后端以及附件。sqlite 通过利用虚拟机和虚拟数据库引擎(vdbe),使调试、修改和扩展 sqlite 的内核变得更加方便。

特点:

面向资源有限的设备,

没有服务器进程,

所有数据存放在同一文件中跨平台,

可自由复制。

sqlite 内部结构:

​ sqlite 基本上符合 sql-92 标准,和其他的主要 sql 数据库没什么区别。它的优点就是高效,android 运行时环境包含了完整的 sqlite。

sqlite 和其他数据库最大的不同就是对数据类型的支持,创建一个表时,可以在 create table 语句中指定某列的数据类型,但是你可以把任何数据类型放入任何列中。当某个值插入数据库时,sqlite 将检查它的类型。如果该类型与关联的列不匹配,则 sqlite 会尝试将该值转换成该列的类型。如果不能转换,则该值将作为其本身具有的类型存储。比如可以把一个字符串(string)放入 integer 列。sqlite 称这为“弱类型”(manifest typing.)。 此外,sqlite 不支持一些标准的 sql 功能,特别是外键约束(foreign key constrains),嵌套 transcaction 和 right outer join 和 full outer join, 还有一些 alter table 功能。 除了上述功能外,sqlite 是一个完整的 sql 系统,拥有完整的触发器,交易等等。

android 集成了 sqlite 数据库 android 在运行时(run-time)集成了 sqlite,所以每个 android 应用程序都可以使用 sqlite 数据库。

对于熟悉 sql 的开发人员来时,在 android 开发中使用 sqlite 相当简单。但是,由于 jdbc 会消耗太多的系统资源,所以 jdbc 对于手机这种内存受限设备来说并不合适。因此,android 提供了一些新的 api 来使用 sqlite 数据库,android 开发中,程序员需要学使用这些 api。

数据库存储在 data/< 项目文件夹 >/databases/ 下。 android 开发中使用 sqlite 数据库 activites 可以通过 content provider 或者 service 访问一个数据库。

下面会详细讲解如果创建数据库,添加数据和查询数据库。 创建数据库 android 不自动提供数据库。在 android 应用程序中使用 sqlite,必须自己创建数据库,然后创建表、索引,填充数据。

android 提供了 sqliteopenhelper 帮助你创建一个数据库,你只要继承 sqliteopenhelper 类,就可以轻松的创建数据库。sqliteopenhelper 类根据开发应用程序的需要,封装了创建和更新数据库使用的逻辑。

sqliteopenhelper 的子类,至少需要实现三个方法:

1 构造函数调用父类 sqliteopenhelper 的构造函数。这个方法需要四个参数:上下文环境(例如,一个 activity),数据库名字,一个可选的游标工厂(通常是 null),一个代表你正在使用的数据库模型版本的整数。

2 oncreate()方法它需要一个 sqlitedatabase 对象作为参数,根据需要对这个对象填充表和初始化数据。

3 onupgrage() 方法,它需要三个参数,一个 sqlitedatabase 对象,一个旧的版本号和一个新的版本号,这样你就可以清楚如何把一个数据库从旧的模型转变到新的模型。

下面示例代码展示了如何继承 sqliteopenhelper 创建数据库:

public class databasehelper extends sqliteopenhelper {  
 databasehelper(context context, string name, cursorfactory cursorfactory, int version) 
 {   
  super(context, name, cursorfactory, version);   
   }   

   @override  
   public void oncreate(sqlitedatabase db) {   
     // todo 创建数据库后,对数据库的操作   
   }   

   @override  
 public void onupgrade(sqlitedatabase db, int oldversion, int newversion) {   
     // todo 更改数据库版本的操作   
   }   

 @override  
 public void onopen(sqlitedatabase db) {   
     super.onopen(db);    
     // todo 每次成功打开数据库后首先被执行   
   }   
 }  

接下来讨论具体如何创建表、插入数据、删除表等等。调用 getreadabledatabase() 或 getwriteabledatabase() 方法,你可以得到 sqlitedatabase 实例,具体调用那个方法,取决于你是否需要改变数据库的内容:

 db=(new databasehelper(getcontext())).getwritabledatabase();
    return (db == null) ? false : true; 

上面这段代码会返回一个 sqlitedatabase 类的实例,使用这个对象,你就可以查询或者修改数据库。 当你完成了对数据库的操作(例如你的 activity 已经关闭),需要调用 sqlitedatabase 的 close() 方法来释放掉数据库连接。 创建表和索引 为了创建表和索引,需要调用 sqlitedatabase 的 execsql() 方法来执行 ddl 语句。如果没有异常,这个方法没有返回值。

例如,你可以执行如下代码:

db.execsql("create table mytable (_id integer primary key autoincrement, title text, value real);"); 

这条语句会创建一个名为 mytable 的表,表有一个列名为 _id,并且是主键,这列的值是会自动增长的整数(例如,当你插入一行时,sqlite 会给这列自动赋值),另外还有两列:title( 字符 ) 和 value( 浮点数 )。 sqlite 会自动为主键列创建索引。 通常情况下,第一次创建数据库时创建了表和索引。

如果你不需要改变表的 schema,不需要删除表和索引 . 删除表和索引,需要使用 execsql() 方法调用 drop index 和 drop table 语句。 给表添加数据 上面的代码,已经创建了数据库和表,现在需要给表添加数据。有两种方法可以给表添加数据。

像上面创建表一样,你可以使用 execsql() 方法执行 insert, update, delete 等语句来更新表的数据。execsql() 方法适用于所有不返回结果的 sql 语句。

例如: db.execsql(“insert into widgets (name, inventory)”+ “values (‘sprocket', 5)”);

另一种方法是使用 sqlitedatabase 对象的 insert(), update(), delete() 方法。这些方法把 sql 语句的一部分作为参数。

示例如下:

contentvalues cv=new contentvalues();
cv.put(constants.title, "example title");
cv.put(constants.value, sensormanager.gravity_death_star_i);
db.insert("mytable", getnullcolumnhack(), cv);

update()方法有四个参数,分别是表名,表示列名和值的 contentvalues 对象,可选的 where 条件和可选的填充 where 语句的字符串,这些字符串会替换 where 条件中的“?”标记。

update() 根据条件,更新指定列的值,所以用 execsql() 方法可以达到同样的目的。 where 条件和其参数和用过的其他 sql apis 类似。

例如:

string[] parms=new string[] {“this is a string”};
db.update(“widgets”, replacements, “name=?”, parms); 

delete() 方法的使用和 update() 类似,使用表名,可选的 where 条件和相应的填充 where 条件的字符串。 查询数据库 类似 insert, update, delete,有两种方法使用 select 从 sqlite 数据库检索数据。

1.使用 rawquery() 直接调用 select 语句; 使用 query() 方法构建一个查询。

raw queries 正如 api 名字,rawquery() 是最简单的解决方法。通过这个方法你就可以调用 sql select 语句。

例如: cursor c=db.rawquery( “select name from sqlite_master where type='table' and name='mytable'”, null);

在上面例子中,我们查询 sqlite 系统表(sqlite_master)检查 table 表是否存在。返回值是一个 cursor 对象,这个对象的方法可以迭代查询结果。 如果查询是动态的,使用这个方法就会非常复杂。

例如,当你需要查询的列在程序编译的时候不能确定,这时候使用 query() 方法会方便很多。

regular queries query() 方法用 select 语句段构建查询。select 语句内容作为 query() 方法的参数,比如:要查询的表名,要获取的字段名,where 条件,包含可选的位置参数,去替代 where 条件中位置参数的值,group by 条件,having 条件。 除了表名,其他参数可以是 null。所以,以前的代码段可以可写成:

string[] columns={“id”, “inventory”};

string[] parms={“snicklefritz”}; 
cursor result=db.query(“widgets”, columns, “name=?”,parms, null, null, null);

使用游标

不管你如何执行查询,都会返回一个 cursor,这是 android 的 sqlite 数据库游标,

使用游标,你可以:

通过使用 getcount() 方法得到结果集中有多少记录;

通过 movetofirst(), movetonext(), 和 isafterlast() 方法遍历所有记录;

通过 getcolumnnames() 得到字段名;

通过 getcolumnindex() 转换成字段号;

通过 getstring(),getint() 等方法得到给定字段当前记录的值;

通过 requery() 方法重新执行查询得到游标;

通过 close() 方法释放游标资源;

例如,下面代码遍历 mytable 表:

cursor result=db.rawquery(“select id, name, inventory from mytable”); 
result.movetofirst(); 
while (!result.isafterlast()) { 
int id=result.getint(0); 
string name=result.getstring(1); 
int inventory=result.getint(2); 
// do something useful with these 
result.movetonext(); 
}

result.close();

在android 中使用 sqlite 数据库管理工具 在其他数据库上作开发,一般都使用工具来检查和处理数据库的内容,而不是仅仅使用数据库的 api。

使用 android 模拟器,有两种可供选择的方法来管理数据库。

首先,模拟器绑定了 sqlite3 控制台程序,可以使用 adb shell 命令来调用他。只要你进入了模拟器的 shell,在数据库的路径执行 sqlite3 命令就可以了。

数据库文件一般存放在: /data/data/your.app.package/databases/your-db-name 如果你喜欢使用更友好的工具,你可以把数据库拷贝到你的开发机上,使用 sqlite-aware 客户端来操作它。这样的话,你在一个数据库的拷贝上操作,如果你想要你的修改能反映到设备上,你需要把数据库备份回去。

把数据库从设备上考出来,你可以使用 adb pull 命令(或者在 ide 上做相应操作)。

存储一个修改过的数据库到设备上,使用 adb push 命令。 一个最方便的 sqlite 客户端是 firefox sqlite manager 扩展,它可以跨所有平台使用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网