第8章 数据存储与访问_第1页
第8章 数据存储与访问_第2页
第8章 数据存储与访问_第3页
第8章 数据存储与访问_第4页
第8章 数据存储与访问_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章

数据存储与访问

本章学习目标:掌握SharedPreferences的使用方法掌握各种文件存储的区别与适用情况掌握SQLite数据库的体系结构、建立和操作方法掌握ContentProvider的原理、创建与使用方法8.1简单存储8.1.1SharedPreferencesSharedPreferences是一种轻量级的数据保存方式以NVP(Name/ValuePair,名称/值对)保存SharedPreferences完全屏蔽了对文件系统的操作过程调用SharedPreferences中的函数就可以实现对NVP的保存和读取SharedPreferences访问权限私有(MODE_PRIVATE):仅创建SharedPreferences的程序有权限对其进行读取或写入全局读(MODE_WORLD_READABLE):不仅创建程序可以对其进行读取或写入,其它应用程序也具有读取操作的权限,但没有写入操作的权限全局写(MODE_WORLD_WRITEABLE):所有程序都可以对其进行写入操作,但没有读取操作的权限8.1简单存储8.1.2示例下面将通过SimplePreferenceDemo示例介绍SharedPreferences的文件保存位置和保存格式下图是SimplePreferenceDemo示例的用户界面8.1简单存储8.1.2示例Android系统为每个应用程序建立了与包同名的目录,用来保存应用程序产生的数据文件,包括普通文件SharedPreferences产生的文件就保存在/data/data/<packagename>/shared_prefs目录下Demo中示例回退保存文件后出现

查看方式:命令行下,adbshell8.1简单存储8.1.2示例SaveSetting.xml文件是以XML格式保存的信息,内容如下1<?xmlversion='1.0'encoding='utf-8'standalone='yes'?>2<map>3 <floatname="Height"value="1.81"/>4 <stringname="Name">Tom</string>5 <intname="Age"value="20"/>6</map>8.2文件存储8.2.1内部存储存储在机器自带的存储空间里Android系统允许应用程序创建仅能够自身访问的私有文件,文件保存在设备的内部存储器上保存地点:在Android系统下的/data/data/<packagename>/files目录中文件操作方式:标准Java的IO类和方法Android流式文件操作方式openFileOutput()//写文件openFileInput()//读文件特点:限定文件的保存地点,适合小文件8.2文件存储8.2.1内部存储openFileOutput()如果指定的文件存在,直接打开文件准备写入数据如果指定的文件不存在,则创建一个新的文件格式:publicFileOutputStreamopenFileOutput(Stringname,intmode)第1个参数是文件名称,这个参数不可以包含描述路径的斜杠第2个参数是操作模式,Android系统支持四种文件操作模式

函数的返回值是FileOutputStream类型8.2文件存储8.2.1内部存储openFileOutput文件模式模式

说明

MODE_PRIVATE私有模式,缺陷模式,文件仅能够被创建文件的程序访问,或具有相同UID的程序访问。MODE_APPEND追加模式,如果文件已经存在,则在文件的结尾处添加新数据。MODE_WORLD_READABLE全局读模式,允许任何程序读取私有文件。MODE_WORLD_WRITEABLE全局写模式,允许任何程序写入私有文件。8.2文件存储8.2.1内部存储openFileInput()格式:publicFileInputStreamopenFileInput(Stringname)

参数是文件名称,不允许包含描述路径的斜杠使用openFileInput()函数打开已有文件,并以二进制方式读取数据的示例代码如下1StringFILE_NAME="fileDemo.txt";2FileInputStreamfis=openFileInput(FILE_NAME);34byte[]readBytes=newbyte[fis.available()];5while(fis.read(readBytes)!=-1){6}8.2文件存储8.2.1内部存储InternalFileDemo用户界面图8.2文件存储8.2.2外部存储文件保存于SD卡MicroSD卡使用FAT文件系统,不支持访问模式和权限控制(安全性低)适合大容量文件可以指定SD卡中的文件存放位置需要SD卡的加载权限与写入权限文件保存在/mnt/sdcard(sdcard)目录下8.2文件存储8.2.2外部存储SDcardFileDemo用户界面图8.2文件存储8.2.3资源文件文件与项目在一起,位于项目/res/raw和/res/xml目录中的原始格式文件和XML文件操作原始格式文件可以是任何格式的文件,例如视频格式文件、音频格式文件、图像文件或数据文件等等在应用程序编译和打包时,/res/raw目录下的所有文件都会保留原有格式不变。而/res/xml目录下一般用来保存格式化数据的XML文件,则会在编译和打包时将XML文件转换为二进制格式,用以降低存储器空间占用和提高访问效率,在应用程序运行的时候会以特殊的方式进行访问资源文件有专门的类进行操作8.2文件存储8.2.3资源文件ResourceFileDemo示例演示了如何在程序运行时访问资源文件当用户点击“读取原始文件”按钮时,程序将读取/res/raw/raw_file.txt文件,并将内容显示在界面上,如下图所示8.3

数据库存储8.3.1

SQLite数据库SQLite是一个2000年由D.RichardHipp发布的开源嵌入式关系数据库轻量级数据库SQLite的特点比传统数据库更适合用于嵌入式系统占用资源少,运行高效可靠,可移植性强提供了零配置(zero-configuration)运行模式SQLite数据库的优势可以嵌入到使用它的应用程序中客户端和服务器在同一进程空间运行简化了数据库的管理过程8.3

数据库存储8.3.2手动建库启动Android虚拟机AndroidSDK目录/platform-tools/下启动adbshellLinux命令提示符下输入sqlite3启动sqlite常用命令编号命令说明12.modeMODE?TABLE?设置输入格式13.databases显示数据库名称和文件位置17.quit退出19.schema?TABLE?显示表的创建语句22.tables?PATTERN?显示符合匹配模式的表名8.3

数据库存储8.3.2手动建库创建数据库命令:Sqlite3peopleinfo

如果数据库存在则打开,不存在则创建Create语句创建表1 sqlite>createtablepeopleinfo2 ...>(_idintegerprimarykeyautoincrement,3 ...>nametextnotnull,4 ...>ageinteger,5 ...>heightfloat);6 sqlite>8.3

数据库存储8.3.2手动建库.tables命令,显示当前数据库中的所有表.schema命令查看建立表时使用的SQL命令1 sqlite>.tables2 poepleinfo3 sqlite>1 sqlite>.schema2 CREATETABLEpeopleinfo3 (_idintegerprimarykeyautoincrement,4 nametextnotnull,5 ageinteger,6 heightfloat);7 sqlite>8.3

数据库存储8.3.2手动建库1 sqlite>insertintopeopleinfovalues(null,'Tom',21,1.81);2 sqlite>insertintopeopleinfovalues(null,'Jim',22,1.78);3 sqlite>insertintopeopleinfovalues(null,'Lily',19,1.68);因为_id是自动增加的主键,因此在输入null后,SQLite数据库会自动填写该项的内容_idnameageheight1Tom211.812Jim221.783Lily191.688.3

数据库存储8.3.2手动建库.mode命令支持:column格式,还支持csv格式、html格式、insert格式、line格式、list格式、tabs格式和tcl格式1 sqlite>.modecolumn2 sqlite>select*frompeopleinfo;3 1Tom211.814 2Jim221.785 3Lily191.686 sqlite>8.3

数据库存储8.3.3代码操作在Android系统中,每个应用程序的SQLite数据库被保存在各自的/data/data/<packagename>/databases目录下缺省情况下,所有数据库都是私有的,仅允许创建数据库的应用程序访问,如果需要共享数据库则可以使用ContentProviderSQLiteOpenHelper,打开数据库SQLiteDatabase,执行SQL语句,完成数据查询与更新流程:创建数据表打开数据库插入,更新,删除,查询关闭数据库8.3

数据库存储8.3.3代码操作SQLiteDemo用户界面8.3.3代码操作SQLiteOpenHelper方法getReadableDatabase()会先以读写方式打开数据库,如果磁盘空间满了,数据库打开失败,会以只读打开,如果问题解决,只读对象就会关闭,返回可读写对象getWritableDatabase()创建或打开一个可以读写的数据库8.3

数据库存储8.3.3代码操作SQLiteOpenHelper运行机制如果数据库不存在,调用onCreat(),不调用onUpgrade();如果数据库存在,但是版本不一样,调用onUpgrade(),不调用onCreate();如果数据库存在,版本也一样,调用onCreate()和onUpgrade();当调用getWritableDatabase,getReadableDatabase如果数据库没有打开,就调用onOpen方法,如果打开了就不调onOpen;

数据库的表的创建一般都在SQLiteOpenHelper的onCreat()中,表字段升级,都会在onUpgrade()处理;8.3

数据库存储8.3.3代码操作数据库操作insert(Stringtable,StringnullColumnHack,ContentValuesvalues)//第二个参数一般为null,表示允许插入空值update(Stringtable,ContentValuesvalues,StringwhereClause,String[]whereArgs)delete(Stringtable,StringwhereClause,String[]whereArgs)Cursorquery(Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy,Stringlimit)execSQL()执行insert、delete、update和CREATETABLE之类有更改行为的SQL语句;rawQuery()方法用于执行select语句。

8.3

数据库存储SQLiteDatabasequery参数说明位置

类型+名称

说明

1Stringtable表名称2String[]columns返回的属性列名称3Stringselection查询条件4String[]selectionArgs如果在查询条件中使用通配符(?),则需要在这里定义替换符的具体内容5StringgroupBy分组方式6Stringhaving定义组的过滤器7StringorderBy排序方式8.4

数据分享8.4.1ContentProviderAndroid应用程序运行在不同的进程空间中,不同应用程序的数据是不能够直接访问的ContentProvider是应用程序之间共享数据的一种接口机制,可以指定需要共享的数据,而其它应用程序则则可在不知道数据来源、路径的情况下,对共享数据进行查询、添加、删除和更新等操作ContentProvider完全屏蔽了数据提供组件的数据存储方法调用者无需知道数据提供者的内部数据的存储方法8.4

数据分享8.4.1ContentProvider调用者不能直接调用ContentProvider的接口函数,而需要使用ContentResolver对象,通过URI间接调用ContentProvider,调用关系如下图所示8.4

数据分享8.4.1ContentProvider调用ContentResolver对象通过URI确定要访问的ContentProvider数据集URI是通用资源标志符(UniformResourceIdentifier),用来定位远程或本地的可用资源ContentProvider使用的URI语法结构如下1 content://<authority>/<data_path>/<id>content://是通用前缀,表示该URI用于ContentProvider定位资源<authority>授权者,确定哪个ContentProvider提供资源一般<authority>都由类的小写全称组成,以保证唯一性。<data_path>是数据路径,用来确定请求的是哪个数据集8.4

数据分享8.4.1ContentProvider调用如果请求的数据并不只限于一条数据,则<id>是可以省略,例如

请求整个people数据集的URI应写为1content://edu.hrbeu.peopleprovider/people请求people数据集中第3条数据的URI则应写为1content://edu.hrbeu.peopleprovider/people/38.4

数据分享8.4.2创建数据提供者ContentProvider程序开发人员通过继承ContentProvider类可以创建一个新的数据提供者,过程可以分为三步继承ContentProvider,并重载六个函数声明CONTENT_URI,实现UriMatcher注册ContentProvider8.4

数据分享8.4.2创建数据提供者1.创建ContentProvider,重载六个函数新建立的类继承ContentProvider后,共有六个函数需要重载,分别是delete():删除数据集insert():添加数据集qurey():查询数据集update():更新数据集onCreate():初始化底层数据集和建立数据连接等工作getType():返回指定URI的MIME数据类型如果URI是单条数据,则返回的MIME数据类型应以vnd.android.cursor.item开头如果URI是多条数据,则返回的MIME数据类型应以vnd.android.cursor.dir/开头8.4

数据分享8.4.2创建数据提供者2.声明CONTENT_URI和构造UriMatcher的代码如下1 publicstaticfinalStringAUTHORITY="edu.hrbeu.peopleprovider";2 publicstaticfinalStringPATH_SINGLE=“people/#”;//单条数据路径,#可以代表任何数字3 publicstaticfinalStringPATH_MULTIPLE=“people”;//多条数据路径4 publicstaticfinalStringCONTENT_URI_STRING="content://"+AUTHORITY+"/"+PATH_MULTIPLE;5 publicstaticfinalUriCONTENT_URI=Uri.parse(CONTENT_URI_STRING);6 privatestaticfinalintMULTIPLE_PEOPLE=1;//返回代码7 privatestaticfinalintSINGLE_PEOPLE=2;8 9 privatestaticfinalUriMatcheruriMatcher;10 static{11 uriMatcher=newUriMatcher(UriMatcher.NO_MATCH);12 uriMatcher.addURI(AUTHORITY,PATH_SINGLE,MULTIPLE_PEOPLE);13 uriMatcher.addURI(AUTHORITY,PATH_MULTIPLE,SINGLE_PEOPLE);14 }8.4

数据分享8.4.2创建数据提供者UriMatcher,识别来访者需要调用多条还是单数数据使用UriMatcher时,则可以直接调用match()函数,对指定的URI进行判断,示例代码如下1switch(uriMatcher.match(uri)){2 caseMULTIPLE_PEOPLE:3 //多条数据的处理过程4 break;5 caseSINGLE_PEOPLE:6 //单条数据的处理过程7 break;8 default:9 thrownewIllegalArgumentException("不支持的URI:"+uri);10}8.4

数据分享8.4.2创建数据提供者3.注册ContentProvider在完成ContentProvider类的代码实现后,需要在AndroidManifest.xml文件中进行注册注册ContentProvider使用<provider>标签,示例代码如下1 <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">2 <providerandroid:name=".PeopleProvider"3 android:authorities="edu.hrbeu.peopleprovider"/>4 </application>在上面的代码中,注册了一个授权者名称为edu.hrbeu.peopleprovider的ContentProvider,其实现类是PeopleProvider8.4

数据分享8.4.3使用数据提供者每个Android组件都具有一个ContentResolver对象,获取ContentResolver对象的方法是调用getContentResolver()函数ContentResolverresolver=getContentResolver();8.4

数据分享8.4.3使用数据提供者查询操作在获取到ContentResolver对象后,程序开发人员则可以使用query()函数查询目标数据下面的代码是查询ID为2的数据1 StringKEY_ID="_id";2 StringKEY_NAME="name";3 StringKEY_AGE="age";4 StringKEY_HEIGHT="height";5 6 Uriuri=Uri.parse(CONTENT_URI_STRING+"/"+"2";7 Cursorcursor=resolver.query(uri,8 newString[]{KEY_ID,KEY_NAME,KEY_AGE,KEY_HEIGHT},null,null,null);8.4

数据分享8.4.3使用数据提供者查询操作ContentResolver的query()函数语法结构如下1 Cursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder)uri定义了查询的数据集projection定义了从应返回数据的哪些属性selection定义了返回数据的查询条件selectArgs,查询参数sortOrder查询结果排序8.4

数据分享8.4.3使用数据提供者添加操作insert()函数,向ContentProvider中添加一条数据bultInsert()函数,批量的添加数据1 ContentValuesvalues=newContentValues();2 value

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论