在这里,我们将给大家分享关于android数据存储的知识,让您更了解一的本质,同时也会涉及到如何更有效地5种Android数据存储方式汇总、Android数据存储---数据备份(DataBackup)
在这里,我们将给大家分享关于android数据存储的知识,让您更了解一的本质,同时也会涉及到如何更有效地5种Android数据存储方式汇总、Android 数据存储 --- 数据备份(Data Backup)(一)、Android——数据存储(三)(SQLite存储)、Android学习之基础知识九—数据存储(持久化技术)的内容。
本文目录一览:- android数据存储(一)(android 数据存储)
- 5种Android数据存储方式汇总
- Android 数据存储 --- 数据备份(Data Backup)(一)
- Android——数据存储(三)(SQLite存储)
- Android学习之基础知识九—数据存储(持久化技术)
android数据存储(一)(android 数据存储)
在android开发中,数据存储是项目中经常会用到的,我们需要掌握它。
其中数据存储包括 sp存储,安卓内置存储和外置存储,数据库存储,以及远程存储。除了最后一个少用,其他几个都要学会。
一、sp存储
这种存储方式适合存数据小,这个翻译就是偏好设置,一般存储一些个人信息等。以键值对的方式生成在对应目录,文件名自定义,文件后缀是固定的.xml
/data/data/packageName/shared_prefs/xxx.xml
需要通过SharedPreferences接口进行操作
案例:
我们通过界面来练习相关api,布局很简单
<LinearLayout xmlns:android
5种Android数据存储方式汇总
本文介绍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,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,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,parms,null,null);
使用游标
不管你如何执行查询,都会返回一个 Cursor,这是 Android 的 sqlite 数据库游标,
使用游标,你可以:
通过使用 getCount() 方法得到结果集中有多少记录;
通过 movetoFirst(),movetoNext(),和 isAfterLast() 方法遍历所有记录;
通过 getColumnNames() 得到字段名;
通过 getColumnIndex() 转换成字段号;
通过 getString(),getInt() 等方法得到给定字段当前记录的值;
通过 requery() 方法重新执行查询得到游标;
通过 close() 方法释放游标资源;
例如,下面代码遍历 mytable 表:
Cursor result=db.rawQuery(“SELECT ID,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 扩展,它可以跨所有平台使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
Android 数据存储 --- 数据备份(Data Backup)(一)
Android 的 backup 服务允许把持久化的应用程序数据拷贝到远程的 “云” 存储,以便给应用程序的数据和设置提供一个还原点。如果用户执行了恢复出厂设置或者把应用转换到一个新的 Android 设备上,系统就会在应用程序被重新安装时,自动的恢复备份的数据。这样用户就不需要在重新复制之前的数据或设置。这个过程对用户来说是完全透明的,并且不会影响到应用程序中功能或用户体验。
在备份操作期间,Android 的备份管理器(BackupManager 对象)会查询应用程序要备份的数据,然后会把查询到的数据交给一个备份传输器,让它把数据发送给云端的存储器。在恢复操作期间,备份管理器从备份传输器中获取备份数据,并把它返回给应用程序,以便应用程序能够把数据恢复给设备。由应用程序来要求数据恢复操作是可能的,但这不是必须的,因为在应用程序被按照并有跟这个用户相关联的备份数据存在时,Android 会自动的执行一个恢复操作。恢复备份数据的主要场景是在用户重置了设备设置,或者升级到了一个新设备,并重新安装了之前安装的应用程序的时候。
注意:备份服务不是为同步应用的数据而设计的,因此不能按需求读写备份数据,并且也不能通过备份管理器提供的 API 以外的方法来访问备份数据。
备份传输器是 Android 备份框架的一个客户端组件,它可以由设备制造商或服务提供者来定制。备份传输器可能会因设备而有所不同,并且任何设备上的备份传输器对应用程序是透明的。备份管理器的 API 把应用程序与给定设备上的实际备份传输器进行了隔离,也就是说应用程序通过一组固定的 API 与备份管理器进行通信,而不管底层的数据传输。
数据备份组件并不保证在所有的 Android 设备上都是可用的。然而,即使一个设备没有提供备份传输器,那么应用也不会受到不利的影响。如果确定用户会从应用程序的数据备份中获益,那么可以根据本文档的描述来实现它,然后发布与实际由哪些设备来执行备份操作无关的应用程序。这样应用程序在没有提供备份传输功能的设备上运行时,应用程序也能正常操作,但不接受来自备份管理器的备份数据的回调。
备份数据不能被设备上的其他应用程序所读取,只有备份管理器和备份传输器在备份操作期间能够访问要备份的数据。
警告:因为云端存储与传输服务会因设备而有所差异,Android 并不保证备份数据的安全行,因此在备份敏感数据时要始终保持警惕,如用户名和口令数据。
基础
如果要备份应用程序数据,就要实现一个备份代理。备份管理器调用备份代理来提供要备份的数据。应用程序重新安装时,也会调用这个代理来恢复数据。备份管理器会处理所有与云端存储有关的数据事务(使用备份传输器来处理),数据备份代理会处理所有的与本地设备相关的数据事务。
以下是实现备份代理的必须步骤:
1. 在清单文件中用 android:backupAgent 属性来声明备份代理;
2. 给应用程序注册备份服务,Google 提供了 Android Backup Service(https://developers.google.com/android/backup/?hl=zh-CN)来作为大多数的 Android 设备的备份服务。为了让这个服务工作,它要求把应用程序注册到这个服务中。为了把数据保存到服务器上,可能还要注册一些其他的可用的备份服务。
3. 通过以下方式之一来定义备份代理:
A. 继承 BackupAgent 类
backupAgent 类提供了应用程序跟备份管理通信的核心接口。如果直接继承这个类,必须重写 onBackup() 和 onRestore() 方法,以便处理 备份和恢复数据的操作。
B. 继承 BackupAgentHelper 类
BackupAgentHelper 类围绕 BackupAgent 类提供了方便的封装,它只需要编写很少的代码。在 BackupAgentHelper 的扩展类中,必须使用一个或多个 helper 对象,它能够自动的备份和恢复某种类型的数据,因此不需要自己来实现 onBackup() 和 onRestore() 方法。
Android 当前提供了备份和恢复 SharedPreferences 和内部存储文件的备份 helper。
原文链接: http://blog.csdn.net/fireofstar/article/details/7530130
Android——数据存储(三)(SQLite存储)
sqlite存储
sqlite是Android系统内置的数据库,是一款轻量级的关系型数据库,支持标准的sql语法,数据库文件存放在/data/data/<package name>/database/目录下。
Android提供了一个帮助类sqliteOpenHelper来简单的对数据库进行创建和升级,sqliteOpenHelper是抽象类,需要重写两个抽象方法:onCreate()和onUpgrade(),分别实现创建和升级数据库。
- onCreate(sqliteDatabase db):第一次创建数据库时调用。
- onUpgrade(sqliteDatabase db, int oldVersion, int newVersion):当数据库需要升级时调用。
sqliteOpenHelper中还有两个实例方法用于创建或打开一个数据库(数据库存在就直接打开,不存在就创建一个新数据库),并返回一个可对数据库进行读写操作的对象(sqliteDatabase):getReadableDatabase()和getWritableDatabase()。
添加数据两种方式(行):
(1)获取sqliteDatabase对象,然后使用ContentValues来对要添加的数据进行组装:put(),然后调用sqliteDatabase对象的insert()方法将ContentValues数据添加到数据库表中:
sqliteDatabase db = dbhelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("name","The Da Vinci Code"); values.put("author","Dan brown"); values.put("pages",454); values.put("price",16.96); db.insert("Book",null,values);
put()方法的第一个参数是要插入数据的索引,第二个参数是要插入的数据。
Insert()方法的第一个参数是要插入的表的名字,第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,第三个参数是一个ContentValues对象。
(2)获取sqliteDatabase对象,调用execsql()方法执行sql插入语句:
sqliteDatabase db = dbhelper.getWritableDatabase(); db.execsql(“insert into Book (name,author,pages,price) values(?,?,?,?)”,new String[]{“The Da Vinci Code”,” Dan brown”,” 454”,” 16.96”});
更新数据的两种方式:
(1)获取sqliteDatabase对象,使用ContentValues来对要更新的数据进行组装,然后调用sqliteDatabase对象的update()方法将ContentValues数据更新到数据库表中:
sqliteDatabase db = dbhelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("price",10.99); db.update("Book",values,"name = ?",new String[]{"The Da Vinci Code"});
update()方法的第一个参数是要插入的表的名字,第二个参数是ContentValues对象,要把更新的数据在这里组装进去,第三、四个参数用于约束更新某一行或某几行的数据,不指定的话默认就是更新所有行。
(2) 获取sqliteDatabase对象,调用execsql()方法执行sql更新语句:
sqliteDatabase db = dbhelper.getWritableDatabase(); db.execsql(“update Book set price = ? where name = ?”,new String[]{“10.99”,” The Da Vinci Code”});
删除数据的两种方式:
(1)获取sqliteDatabase对象,调用delete()方法进行删除操作:
sqliteDatabase db = dbhelper.getWritableDatabase(); db.delete("Book","pages > ?",new String[]{"500"});
delete()方法第一个参数是要插入的表的名字,第二、三个参数是用于约束删除某一行或某几行的数据,不指定的话就是默认删除所有行。
(2)获取sqliteDatabase对象,调用execsql()方法执行sql删除语句:
sqliteDatabase db = dbhelper.getWritableDatabase(); Db.execsql(“delete from Book where pages > ?”,new String[]{“500”});
查询数据的两种方式:
(1)获取sqliteDatabase对象,调用query()方法进行查询(这里只详细讲解七个参数的):
query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
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对象,查询的所有数据将从这个对象中取出。
查询书本页数大于400的书的信息:
sqliteDatabase db = dbhelper.getWritableDatabase(); Cursor cursor = db.query("Book",new String[]{"name","author","pages","price"},"pages > ?",new String[]{"400"},null,null,null);
查询所有书的信息:
sqliteDatabase db = dbhelper.getWritableDatabase(); Cursor cursor = db.query("Book",null,null,null,null,null,null);
(2)获取sqliteDatabase对象,调用rawQuery()方法进行查询:
rawQuery (String sql, String[] selectionArgs)
查询书本页数大于400的书的信息:
sqliteDatabase db = dbhelper.getWritableDatabase(); Cursor cursor = db.rawQuery("select * from Book where pages > ?",new String[]{"400"});
查询所有书的信息:
sqliteDatabase db = dbhelper.getWritableDatabase(); Cursor cursor = db.rawQuery("select * from Book ",null);
提取查询到的数据,调用Cursor对象的movetoFirst()方法将数据的指针移动到第一行的位置,然后进入到循环中,遍历查询到的每一行数据,getColumnIndex()用于获取某一列在表中对应的位置索引。然后将这个索引传入到相应的取值方法中就可以提取出数据了,每遍历一次就调用movetoNext()方法将数据指针移动到下一行:
if (cursor.movetoFirst()){ do { //遍历cursor对象,取出数据打印 String name = cursor.getString(cursor.getColumnIndex("name")); String author = cursor.getString(cursor.getColumnIndex("author")); int pages = cursor.getInt(cursor.getColumnIndex("pages")); double price = cursor.getDouble(cursor.getColumnIndex("price")); Log.d("MainActivity","book name is "+name); Log.d("MainActivity","book author is "+author); Log.d("MainActivity","book pages is "+pages); Log.d("MainActivity","book price is "+price); }while (cursor.movetoNext()); } cursor.close();
Android学习之基础知识九—数据存储(持久化技术)
数据持久化是将那些内存中的瞬时数据保存到存储设备,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失。
Android系统中主要提供了3种方式用于简单地实现数据持久化功能:文件存储、SharedPreference存储、数据库存储。除了这三种方式外,还可以将数据保存在手机的SD卡中,不过相对比较麻烦,而且安全性方面也相对较低。下面我们就来了解一下这三种数据持久化的方式:
一、文件存储
文件存储是Android中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有的数据都原原封不动的保存在文件当中,因此它比较适合用于存储一些简单的文本数据或二进制数据。如果你想要使用文件存储的方式来保存一些较为复杂的文本数据,就需要定义一套自己的格式规范,这样可以方便之后将数据从文件中重新解析出来。
1.1、将数据存储在文件中
第一步:创建项目:FilePersistenceTest,在activity_main.xml中设置一个输入框
第二步:将在输入框中输入的数据保存在文件中
第三步:运行程序,输入一段文字后,点击Back键退出程序
第四步:查看文件
我们在保存数据的时候,只设置了文件名,而没有设置保存路径,这是因为所有的文件默认都是保存在:/data/data/包名/files/目录下,要找到这个路径,需要打开:Android Device Monitor,步骤如下:
找到SDK目录 ---> tools目录下 ---> 点击monitor.bat打开 --->找到:File Explore栏 ---> 该栏下到:/data/data/com.workspace.hh.filepersistencetest/files/data.(注意:这里的包名是你自己的包名)---> 找到后点击右上角的导出按钮,将data文件导出并打开。
1.2、从文件中取出数据
第一步:取出数据,下面代码中有两个地方需要注意:
1、调用EditText的:setSelection()方法是为了将输入的光标移动到文本的末尾位置,以便于继续输入。
2、对字符串进行非空判断的时候,使用了:TextUtils.isEmpty()方法,这是一个非常好的方法,它可以进行两种空值的判断,当传入的字符串等于null或者等于空字符串的时候,这个方法都是返回的true.所以我们不需要先单独判断这两种空值再使用逻辑运算符连接起来了。
第二步:运行程序(左),我们重新输入文字(中),然后点击Back键退出程序后,再打开程序(右)
1.3、总结
文件存储用到的核心就是Context类提供的:openFileInput()和openFileOutput()两种方法。但是它不适合用于存储一些较为复杂的文本数据。
二、SharedPreferences存储
SharedPreferences存储是另一种数据持久化的方式,它比文件存储更加简单易用,而且可以很方便对某一指定的数据进行读写存储。不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的。也就是说,当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且SharedPreferences还支持很多不同的数据类型存储,如果存储的数据类型是整型,那么读出来的数据也是整型的;如果存储的数据是一个字符串,那么读取出来的数据仍然是字符串。
2.1、将数据存储到SharedPreferences中
要想使用SharedPreferences来存储数据,首先要获取到SharedPreferences对象。Android中主要提供了三种方法用于得到SharedPreferences对象:
第一种:Context类中的:getSharedPreferences()方法
这个方法接收两个参数,第一个参数指定SharedPreferences文件的名称,如果文件不存在就会自动创建一个,SharedPreferences文件都是存放在:/data/data/项目包名/shared_prefs/目录下。第二个参数用于指定操作模式,目前只有:MODE_PRIVATE这一种模式可选。它是默认的操作模式,和直接传入0的效果是相同的,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写,其他几种操作模式均已被废弃。
第二种:Activity类中的:getPreferences()方法
这个方法和Context中的:getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreferences的文件名。
第三种:PreferenceManager类中的:getDefaultSharedPreferences()方法
这个方法是一个静态的方法,它接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件。
上面是三种得到SharedPreferences对象的方法,得到SharedPreferences对象之后,就可以开始向SharedPreferences文件存储数据了,主要分为三步实现:
(1)调用SharedPreferences对象的:edit()方法来获取一个SharedPreferences.Editor对象
(2)向SharedPreferences.Editor对象中添加数据,比如添加一个布尔型数据就使用:putBoolean()方法,添加一个字符串则使用:putString()方法,以此类推。
(3)调用:apply()方法将添加的数据提交,从而完成数据存储操作。
下面我们就来体验一下SharedPreferences存储的用法:
第一步:新建SharedPreferencesTest项目,在activity_main.xml中设置一个按钮
第二步:在活动中给按钮添加监听事件,实现通过点击按钮来保存指定数据的功能,这里是通过第一种方法来获取的SharedPreferences对象。
第三步:运行程序,打开Android Device Monitor,找到:/data/data/项目包名/shared_prefs/目录下的data文件
第四步:导出文件并打开,我们可以看到数据是使用XML格式来保存的。
2.2、从SharedPreferences中读取数据
SharedPreferences对象中提供 一系列get方法,用于对存储的数据进行读取,每种get方法都对应了SharedPreferences.Editor中的一种put方法,比如读取一个布尔型数据就使用getBoolean()方法,读取一个字符串就使用:getString()方法,这些get方法都接收两个参数,第一个参数是键,传入存储数据时使用的键就可以得到相应的值了;第二个参数是默认值,即表示当传入的键找不到对应的值时会以什么样的默认值进行返回。
相对于保存数据,取出数据就更加简单了:
第一步:设置一个取出数据的按钮:Restore Data
第二步:设置按钮的监听事件,通过点击按钮将取出的数据打印出来
第三步:运行程序,点击按钮,查看打印出来的日志,这样我们就把数据取出来了。
2.3、实现记住密码的功能
第一步:借助BroadcastBestPractice项目,在该项目中直接编辑。首先在登录界面设置一个复选框和提示记住密码的文本:
CheckBox控件是一个复选框控件,用户可以通过点击的方式来进行选中和取消。
第二步:实现逻辑
代码分析:
首先在onCreate()方法中获取到SharedPreferences对象,然后调用它的getBoolean()方法去获取remember_password这个键对应的值。一开始当然不存在对应的值了,所以会使用默认值false,这样就什么都不会发生。接着在登录成功之后,如果用户想要记住密码,勾选了复选框,这时将remember_password设置为true,然后把account和password对应的值都保存到SharedPreferences文件当中并提交,如果复选框没有被选中,就简单的调用一下clear()方法,将SharedPreferences文件中的数据全部清除掉。
当用户选中了记住密码的复选框,并成功登录一次后,remember_password键对应的值就是true了,这个时候如果再重新启动登录界面,就会从SharedPreferences文件中将保存的账号和密码都读取出来,并填充到文本输入框中,然后把记住密码复选框选中,这样就完成记住密码的功能了。
第三步:运行程序,可以看到界面上多了一个记住密码复选框,点击登录,就会跳转到MainActivity,接着在MainActivity中发出一条强制下线的广播,会让程序重新回到登录界面,此时你会发现,账号和密码都已经填充到界面上了,如下图所示:登录前(左)、登录后(右)
注意:
从上面屏幕上我们看到:Account和Password距离屏幕边框太近,我们在这里可以设置一个:android:layout_margin属性,调整它距离边框的位置:
然后重新运行程序效果如下:
2.4、总结
上面实现的记住密码的功能只是个简单的实例,并不能在实际的项目中直接使用。因为将密码以文明的形式存储在SharedPreferences文件中是非常不安全的,很容易就会被别人盗取,因此在正式的项目里还需要结合一定的算法来对密码进行保护才行。
接着我们开始将第三种数据持久化技术:SQLite数据库存储。由于这一部分涉及的内容很多,我们单独拿一讲来讲述。
关于android数据存储和一的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于5种Android数据存储方式汇总、Android 数据存储 --- 数据备份(Data Backup)(一)、Android——数据存储(三)(SQLite存储)、Android学习之基础知识九—数据存储(持久化技术)的相关信息,请在本站寻找。
本文标签: