邢立国,褚龙现
(平顶山学院 河南 平顶山 467000)
目前大部分应用程序的主要功能都围绕数据处理进行设计,如何高效安全地进行数据存储和访问成为各类应用设计中重点关注的问题[1]。存储应用程序中的数据一般有两种方式,分别是数据文件和数据库。数据文件存储数据方式简洁,但是修改和查询数据困难,所以主要用来存储类型简单且少量数据;数据库需要借助专门的管理系统进行管理,但是对数据进行增加、删除、修改和查询时非常便利,所以可以用来存储需要经常访问的大量数据[2]。在Android应用程序中为了存储和访问数据也采用上述两种方式,其中数据文件存储可以选择XML文件或基本文件[3],而数据库则采用Android内置的SQLite进行管理。本文在分析Android中数据存储方式的基础上,提出了每种存储方式下不同数据的访问技术实现方法,并总结各种访问技术的应用场景。
Android是基于Linux内核的开放式操作系统,允许用户开发应用程序并自由发布[4]。Android平台由四层框架构成,最底层是Linux内核层,提供各种驱动;第二层是库和Android运行时,包含C/C++库、Dalvike虚拟机和Java语言特定函数,用来实现线程管理和内存管理等;第三层是应用程序框架层,是为应用程序提供框架服务的API;最上层是应用程序层,大多是使用Java开发的核心应用和用户自定义的应用[5]。
目前,Android系统主要应用在智能手机和手持平板电脑中,基于Android的应用程序也越来越多。一个Android项目需要保存数据时,可以将数据文件或数据库文件保存在res文件夹下,发布格式是一个经过数字签名的.apk文件包[6]。
Android应用中可以把数据保存到数据文件中,也可以保存到SQLite管理的数据库中[7]。保存方式不同,访问数据时应用技术也不相同。
Android系统中的文件读写主要分为3类:一是基本文件读写,二是简单共享文件读写,三是XML文件读写。
1)基本文件读写
为了保存数据,Android允许应用程序将数据保存在指定位置的文件中。常见的有两种位置:设备内部存储器和SD卡。
①内部存储器文件读写
当应用程序读写内部存储器上文件时,要求文件保存在“/data/data/<package name>/files” 目录中, 且通过简化函数openFileOutput()和 openFileInput()进行操作。
其中写文件提供了四种模式,分别是私有模式,只能被创建文件的程序或具有相同UID的程序访问;追加模式,在文件结尾处添加新数据;全局读,允许任何程序读取私有文件;全局写,允许任何程序写入私有文件。
②SD卡文件读写
SD卡是设备的扩展存储,挂载到Android操作系统的“/mnt/sdcard”目录。可以使用FileInputStream和FileOutputStre am进行读写。
2)简单共享文件读写
为了实现不同进程之间共享数据,Android提供了SharedPreferences类支持简单数据共享。该文件保存在“/data/data/<package name>/shared_prefs”目录中。
①写入SharedPreferences
SharedPreferences sp= getSharedPreferences("config",Context.MODE_PRIVATE);
Editor editor=sp.edit();
editor.putString("uname","root");
editor.putString("pwd","12345");
editor.commit();
程序执行完后得到config.xm l文件,文件主要内容如下:
<map>
<string name="uname">root</string>
<string name="pwd">12345</string>
</map>
②读取SharedPreferences
SharedPreferences sp=getSharedPreferences("config",Context.MODE_PRIVATE);
String name=sp.getString("uname");
String pwd=sp.getString("pwd");
为实现共享,两个应用的sharedUserId的内容要相同,同时双方使用MODE_WORLD_READABLE或MODE_WORLD_WRITEABLE模式读写内容。
3)XML 文件读写
读写XML文件的关键在于如何解析文件,常见的有两种解析方式:SAX(Simple API for XML)和 DOM(Document ObjectModel)。两种解析方式中,SAX占用资源少、速度快,但是不能进行查找和修改;DOM将XML记入内存可以反复查询和修改,但是占用内存多、分析效率低[8]。
Android中提供了 Xm lResourceParser类,实现Xm lPullParser接口,是基于SAX的XML分析器。在使用Xm lResourceParser进行解析时主要依据各种事件类型进行处理。
Android中内置的SQLite数据库管理系统由C语言编写,支持SQL操作[9]。默认情况下,数据库文件保存在“/data/data/<应用程序包>/databases”中,也可以保存到任意有权限访问的目录。
访问SQLite数据库一般分为3个步骤:创建数据库连接、数据操作和关闭连接。
1)创建连接
在Android开发中可以继承SQLiteOpenHelper类实现数据库连接的创建。下面代码创建了到数据库student.db的连接。
public class MyHpr extends SQLiteOpenHelper{//完成数据表创建}
于是,创建连接可以用下面语句完成:
MyHpr hp=new MyHpr(this);
SQLiteDatabase db=hp.getWritableDatabase();
2)数据操作
数据库连接创建完成后可以执行插入、修改、删除和查询操作。
①插入数据方法
ContentValues cv=new ContentValues();
cv.put(列名,列值);
db.insert(表名,null,cv);
②修改数据方法
ContentValues cv=new ContentValues();
cv.put(列名,列值);
db.update(表名,cv,where条件,修改条件中参数值);
③删除数据方法
db.delete(表名,cv,where条件,修改条件中参数值);
④查询数据方法
Cursor c=db.query(表名,select包含字段,where条件,条件中参数值,group子句,having子句,排序字段);
查询操作将返回Cursor对象,通过该对象的moveToNext()方法可以读取下一行数据,通过getType(int ColIndex)方法可以获取指定行中指定列的值。
3)关闭连接
当应用程序暂停、退出或不再需要操作数据库时应该关闭数据库连接:
db.close();
Android应用程序运行在不同的进程空间中,因此不同应用程序的数据不能直接访问。尽管使用SharedPreferences可以简单实现跨进程访问,但存在一定局限性。
ContentProvider是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法,可以指定需要共享的数据,而其他应用程序则可在不知道数据来源、路径的情况下,对共享数据进行查询、添加、删除和更新等操作。
ContentProvider使用的URI语法结构如下
content://<authority>/<data_path>/<id>
创建ContentProvider分为下面3个步骤:
1)继承 ContentProvider
新建立的类继承ContentProvider后,共有6个函数需要重载,如表1所示。
表1 ContentProvider重载Tab.1 ContentProvider overloaded functions
2)声明 CONTENT_URI,实现 UriMatcher
在新构造的ContentProvider类中,经常需要判断URI是单条数据还是多条数据,最简单的方法是构造一个UriMatcher。
private static final UriMatcher uMr;
static{
uMr=new UriMatcher(UriMatcher.NO_MATCH);
uMr.addURI(授权者,单条数据路径,单条标示);
uMr.addURI(授权者,多条数据路径,多条标示);
}
3)注册 ContentProvider
在完成ContentProvider类的代码实现后,需要在AndroidManifest.xm l文件中进行注册。
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<provider android:name=".自定义类名"android:authorities="授权名称"/>
</application>
自定义ContentProvider完成后不需要直接调用类中的方法,而是通过ContentResolver对象进行数据操作。
ContentResolver r=getContentResolver();
ContentValues cv=new ContentValues();
UrinewUri=r.insert(uri,cv);
ContentValues cv1=new ContentValues();
int result=r.update(uri,cv1,where条件,条件中参数值);
int result1=r.delete(uri,where条件,条件中参数值);
Cursor cursor=r.query(uri,select包含字段,where条件,条件中参数值,排序字段);
上述3种数据访问技术都能够实现Android中数据的存储与查询,但是各有其优缺点。在实际项目开发过程中需要根据应用场景确定选用何种数据存储及访问方式。
当需要存储结构化不强且数据量较少的数据时考虑使用文件存储方式。若保存的是“键-值”应用程序配置信息,适合采用SharedPreferences方式,这样既方便存取访问又能实现简单共享。
当数据量较大且经常做数据访问操作时考虑使用数据库存储方式。如果只在一个应用程序内部进行数据访问,直接构造数据库连接进行访问即可;如果需要在多个应用之间进行数据共享访问,则使用ContentProvider实现共享。
通过对Android应用中3种常见数据存储访问技术的研究,阐述了各种访问方式的基本实现方法,最后简单分析各种技术的应用场景。对数据访问技术的研究为更好地理解Android数据存储访问机制和原理,在应用程序开发中合理选用高效的存储访问方式提供重要依据。
[1]燕超霞.基于Android的工程材料信息管理系统的设计与实现[D].郑州:郑州大学,2012.
[2]刘婕.基于Android系统的移动终端通讯录的研究与设计[D].西安:西安电子科技大学,2012.
[3]倪红军.基于Android系统的数据存储访问机制研究[J].计算机技术与发展,2013,23(6):90-93.NIHong-jun.Study of data storage accessmechanism based on android system [J]. Computer Technology and Development,2013,23(6):90-93.
[4]姚昱昱,刘卫国.Android的架构与应用开发研究[J].计算机系统应用,2008,17(11):110-112.YAO Yu-yu,LIUWei-guo.Study of Android architecture and its application development [J].Computer Systems &Applications,2008,17(11):110-112.
[5]公磊,周聪.基于Android的移动终端应用程序开发与研究[J].计算机与现代化,2008(8):85-89.GONG Lei,ZHOU Cong.Development and research ofmobile termination application based on Android[J].Computer and Modernization,2008(8):85-89.
[6]杨超.基于Android平台的电子阅读客户端的设计与实现[D].北京:北京交通大学,2011.
[7]Reto Meier.Professional Android 4 Application Development[M].John Wiley&Sons,Inc.,2012.
[8]朱珊娜,李书琴,安福定.XML文档到关系数据库的转换研究[J].计算机工程与设计,2008,29(21):5507-5509.ZHU Shan-na,LI Shu-qin,AN Fu-ding.Conversion from XML document to relational database [J].Computer Engineering and Design,2008,29(21):5507-5509.
[9]赵珂.基于Android移动终端预约挂号系统的设计与实现[D].武汉:武汉理工大学,2012.