APP下载

Android存储机制的应用研究

2013-12-29李侠沈峰

电脑知识与技术 2013年24期

摘要:Android系统已经广泛应用于手机和平板电脑等移动设备中,开发Android应用程序必须面临如何存储数据的问题。Android系统提供多种数据存储机制。针对开发人员面对如何正确、快速地选择合适的存储机制及在程序中如何正确使用的问题,分析比较首选项、内部存储器文件、外部存储器文件和SQLite数据库引擎的特点和适用场合,阐述存储机制使用的主要步骤、关键API函数、特别是SQLite引擎的使用及与图形用户界面程序的关系等。实现方便开发人员在进行Android软件开发时参考如何选择存储方式和高效地进行程序设计的目的。

关键词:安卓;首选项;文件;数据库引擎;应用程序开发

中图分类号:TN929 文献标识码:A 文章编号:1009-3044(2013)24-5535-04

Android(中文名:安卓)操作系统是一个基于Linux操作系统的完整、开放、免费和开源的智能移动开发平台,可应用于手机、平板电脑和其它嵌入式产品中。基于Android的移动设备目前已经得到广泛应用,根据国际数据公司(IDC) 2012年11月份的数据统计[1],Android 手机的市场份额为75%。丰富多彩的Android应用程序极大方便了我们的生活,同时将进一步扩展Android系统的市场份额。应用程序的核心是算法和数据,应用程序可以使用不同的方式存储和管理数据。Android系统数据存储分为网络存储和本地存储[2]。该文将主要研究Android系统提供的本地数据存储机制,包括应用程序首选项(preference)、文件和内建的SQLite数据库引擎等,为程序开发人员根据应用程序的数据存储需求选择不同的存储机制作有效的参考。

1 首选项的使用方法

首选项方式与其它存储方式相比,它是轻量级的数据存储机制,用以存储应用程序状态、简单的用户信息、配置参数和其他类似的信息[3]。首选项只能应用于其所在的应用程序之中,一个程序不能访问另一个程序的首选项。首选项以“键-值”对的方式存储数据,数据类型包括布尔型、浮点型、整型、长整型和字符串型等。在应用程序中引入android.content.SharedPreferences接口就可以使用首选项,通过SharedPreferences接口可以实现查找、读取、添加和删除各种类型的“键-值”对操作,使用步骤如下:①获取一个SharedPreferences 对象的实例;②创建一个SharedPreferences.Editor来修改首选项内容;③使用Editor修改首选项;④提交所做的修改。首选项分为私有和共享两种。一个应用程序中可以包括一个或多个Activity(或称为活动),一个Activity相当于Windows操作系统下的一个窗口。私有首选项仅供定义其的Activity使用,其它Activity不能访问,其主文件名为Activity的类名。共享首选项可供应用程序中所有的Activity使用,其主文件名可由开发人员自定义。

如下示例程序演示通过以上步骤向私有首选项中添加一个布尔型键值对:

建立共享首选项与建立私有首选项的区别在于共享首选项使用如下语句:

SharedPreferences settings = getSharedPreferences(共享首选项文件名, 0);

首选项以扩展名为xml的文件形式保存在Android文件系统中,文件位于“/data/data/包名/shared_prefs”目录下。用户通过DDMS(Dalvik Debug Monitor Service,DDMS)中的文件浏览器可以访问这些选项文件。

2 文件的使用方法

Android应用程序访问的文件包括资源文件、默认目录下的文件和非默认目录下的文件。

Android系统中存储器分为易失存储器和非易失存储器,易失的存储器指RAM,相当于PC机中的内存。焊接在手机电路板上的非易失存储器,称为内部存储器,可以插拔的非易失存储器例如SD卡称为外部存储器[4] ( External Storage)。默认目录下的文件保存在内部存储器中,非默认目录下的文件保存在外部存储器中。

2.1 资源文件的使用

根据能否被aapt(Android Asset Packaging Tool,aapt)资源打包工具支持,资源文件分成普通资源文件和原始(raw)文件。普通资源文件可以被aapt编译成二进制文件并进行压缩打包,文件内容包括字符串、字符串数组、布尔型、整型、整型数组、混合类型数组、颜色、图像、动画、菜单、XML文件、布局、样式和主题等,种类丰富。原始文件指不被aapt支持的文件类型,常见的包括音频和视频文件。资源文件存储于工程的/res目录下的相应目录,文件名必须小写。对资源文件的访问遵循访问资源的方式,与普通文件访问不一样。

2.2 默认目录下的文件使用

Android应用程序将数据默认存储在“/data/data/包名/files/”目录中,通过getFilesDir()函数可以得到此默认目录。在默认目录下创建并写入文件示例如下:

为了提高应用程序的性能和网络访问的速度,通常需要创建缓存文件来缓存一些应用程序使用的数据。对于缓存文件,默认的存储目录是“/data/data/包名/cache”,通过调用getCacheDir()获得此目录。应用程序应该负责建立和删除自己的缓存文件。当内部存储空间不足或用户卸载应用程序后,Android文件系统将自动删除缓存文件。

2.3 非默认目录下的文件使用

由于内部存储器容量有限,应用程序应该将较大的数据存储在外部存储设备SD卡上,即非默认的目录下。由于SD卡可能随时被用户取走,因此对SD卡进行读写之前,需要首先调用函数 Environment.getExternalStorageState()检查SD卡的状态,包括可读可写、只读、未加载等状态,然后调用getExternalFilesDir()函数获得文件在SD卡上的目录,目录名称如下:/mnt/sdcard/android/data/包名/files。如下示例实现获取一个图像资源,然后把它写入到SD卡对应的应用程序目录中:

3 SQLite数据库管理系统的使用

SQLite是一个轻量级的强大的嵌入式关系数据库引擎,它占用空间低、运行效率高,特别适合嵌入式设备,已经成为一个健壮的数据存储机制[5]。与桌面系统中的数据管理系统如 SQL Server、Orcalce等不同,SQLite数据库包含在磁盘上的一个文件中。SQLite数据库是应用程序私有的,如果其他应用程序共享此数据库,需要把此应用程序变成一个内容提供器。Android中管理数据库操作的类集中在android.database.sqlite包中。另外,Android提供了sqlite3命令工具,可以通过命令行创建和管理数据库的各种操作。应用程序使用的SQLite数据库储存在如下目录:/data/data/包名/database/数据库文件名。

3.1 管理SQLite数据库

管理SQLite数据库时,首先需要创建创建SQLite数据库,然后配置SQLite数据库属性,重要的数据库配置选项包括版本、本地化和线程安全锁特性。主要代码示例如下:

删除数据库直接使用deleteDatabase(“数据库名称”)方法,这种删除是永久性的,数据库的所有数据和表都将删除。

3.2管理表和记录

SQLiteDatabase类中的方法execSQL()可以用来执行任何有效的SQLLite SQL表达式,包括创建、更新和删除数据库表、视图和触发器等。使用时只需要把对应功能的表达式封装成字符串,然后被execSQL函数调用,例如创建数据库中的表可使用如下语句实现:

对表中的记录进行插入、更新、删除和查询的操作分别对应SQLiteDatabase类中的insert()、update()、 delete()和query()方法,这四个方法中的各个参数分别表示对应SQL语句中的不同部分,从而形成一个功能完整的SQL语句。事务操作的方法包括 beginTransaction()、setTransactionSuccessful()和endTransaction()。有关数据库管理的一个重要操作是查询。为了从数据库中获取所需的数据,需要应用程序提供各式各样的查询功能,SQLite为应用程序实现查询提供了多种方式:1) SQLiteDatabase类中的query()方法,实现简单的查询;2)当涉及多个数据库表进行复杂的查询时,通常使用SQLiteQueryBulder()类中的query()方法;3)当执行非常复杂的查询时,方式2)显得比较繁杂,这时可以使用SQLiteDatabase类中的rawQuery方法,此方法只需要一个SQL字符串表达式。如果在字符串表达式中引入“?”,表示可以带可选参数。以上三种方式的返回类型都是Cursor。Cursor像指针一样,可以对查询结果进行随机访问。可以把查询结果看作一个表,其中每一行对应一个返回的记录。Cursor对象包括了一些有用的方法来确定查询返回结果的数量及每一条返回记录的列名称。返回结果中的列由查询本身进行定义,而非数据库表来确定 。

3.3借助SQLiteOpenHelper管理数据库和表

为了提高程序的可读性和程序开发效率,Android提供了一个名为SQLiteOpenHelper的辅助类来管理数据库。使用此类的步骤:1)设计一个合同类(contract);2)继承SQLiteOpenHelper类;3)在主Activity中打开数据库,对表进行各种操作。合同类具体描述如下:为了跟踪数据库中表及其字段,以避免SQL语句中调用这些名称出错,需要设计一个称之为合同的类。这个类相当于一个容器,里面定义多个内部类,每个内部类对应一个表,内部类中的字段定义为字符串常量表示名称、字段名称等。例如:

为了创建数据库和表,需要继承SQLiteOpenHelper并进行对应的扩展,继承这个父类时必须要重载onCreate()、onUpgrade()、onOpen()等方法,其中最常用的是onCreate(),在此方法中创建数据库表。例如:

在主Activity中为了对数据库进行操作,首先实例化SQLiteOpenHelper的子类并打开数据库,例如:

PetTrackerDatabaseHelper mDatabase = null;

然后通过调用SQLiteDatabase 类的对应的方法进行对指定的数据库表进行插入、删除、更新和查询等操作。与3.2节相关内容一致。

3.4向应用程序界面绑定数据

为了可视化的操作数据库,通常需要将应用程序用户界面与数据库中的数据进行绑定。有各种不同的绑定方法。作为程序开发人员,可以使用特定控件提供的内建数据绑定功能。为了更灵活地使用数据,更多情况下开发人员需要使用数据适配器(Data Adapter)向控件绑定数据。通过适配器向应用程序界面绑定数据结构示意图如图1所示:

数据源为数组或通过数据库查询得到的Cursor类型值。适配器类Adapter常用的子类有CursorAdapter和ArrayAdapter,分别表示数据源是数据库和数组。根据数据源不同使用不同的Adapter子类。容器类可以容纳其它简单view控件,典型的容器类有ListView、GridView和GalleryView。容器类位于的布局文件通常是应用程序的主布局文件,此布局文件将重复显示view控件布局模板文件的内容。View控件布局模板文件中放置多个诸如TextView这样的子对象,用于表示要显示的数据表中记录的各个字段值。具体使用步骤如下:

1)执行查询并返回一个有效的Cursor结果或再把此Cursor结果赋值给一个数组,形成数据源;

2)根据数据源不同创建一个对应的适配器,并将数据源的列映射到布局模板文件中的各个对应控件中;

2)将适配器与容器类关联。

4 结论

本文重点研究了在应用程序开发时需要理解的Android本地存储系统的特点、使用步骤和关键类,方便开发人员在进行存储方式选择时进行参考。数据存储方式是开发人员在设计阶段就需要进行处理的问题。首选项方式是是轻量级的数据存储机制,用以存储应用程序状态和配置参数等简单信息。文件方式是最常用的,根据文件存储的位置,默认目录下的文件储存在内部储存器中,非默认目录下的文件存储中外部存储器中,通常应用程序都应该将较大的数据存储在外部存储器中。为了提高程序访问速度,通常还需要在程序中使用缓冲文件。为了储存结构化数据,Android设备引入了SQLite关系型数据库引擎,SQLite将成为一个Android系统中最为健壮的数据存储机制。

参考文献:

[1] Ramon Llamas. Android Marks Fourth Anniversary Since Launch with 75.0% Market Share in Third Quarter, According to IDC[EB/OL].[2013-07-25].http://www.idc.com/getdoc.jsp?containerId=prUS23771812.

[2] Google Inc.Data Storage[EB/OL].[2013-07-25].http://developer.android.com/guide/topics/data/index.html.

[3] Lauren Darcey,Shane Conder.Android移动开发一本就够[M].李卉,译.北京:人民邮电出版社,2011.

[4] 黄伟敏.Android平台的即时通信系统客户端设计方案[J].现代电子技术,2011(16):35-39.

[5] Richard D Hipp.About SQLite[EB/OL].[2013-07-25].http://www.sqlite.org/about.html.