《第8章数据存储与访问课件.ppt》由会员分享,可在线阅读,更多相关《第8章数据存储与访问课件.ppt(43页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第8 8章章 数据存储与访问数据存储与访问 本章学习目标:n掌握SharedPreferences的使用方法n掌握各种文件存储的区别与适用情况n掌握SQLite数据库的体系结构、建立和操作方法n掌握ContentProvider的原理、创建与使用方法8.1 简单存储 n8.1.1 SharedPreferencesqSharedPreferences是一种轻量级的数据保存方式q以NVP(Name/Value Pair,名称/值对)保存qSharedPreferences完全屏蔽了对文件系统的操作过程 q调用SharedPreferences中的函数就可以实现对NVP的保存和读取 qShare
2、dPreferences访问权限n私有(MODE_PRIVATE):仅创建SharedPreferences的程序有权限对其进行读取或写入n全局读(MODE_WORLD_READABLE):不仅创建程序可以对其进行读取或写入,其它应用程序也具有读取操作的权限,但没有写入操作的权限n全局写(MODE_WORLD_WRITEABLE):所有程序都可以对其进行写入操作,但没有读取操作的权限8.1 简单存储 n8.1.2 示例q下面将通过SimplePreferenceDemoSimplePreferenceDemo示例示例介绍SharedPreferences的文件保存位置和保存格式q下图是Simp
3、lePreferenceDemo示例的用户界面8.1 简单存储n8.1.2 示例qAndroid系统为每个应用程序建立了与包同名的目录,用来保存应用程序产生的数据文件,包括普通文件qSharedPreferences产生的文件就保存在/data/data/shared_prefs目录下qDemo中示例回退保存文件后出现 q查看方式:n命令行下,adb shell 8.1 简单存储n8.1.2 示例qSaveSetting.xml文件是以XML格式保存的信息,内容如下1 2 3 4 Tom5 6 8.2 文件存储n8.2.1 内部存储q存储在机器自带的存储空间里qAndroid系统允许应用程序创
4、建仅能够自身访问的私有文件,文件保存在设备的内部存储器上q保存地点:在Android系统下的/data/data/files目录中q文件操作方式:n标准Java的IO类和方法nAndroid流式文件操作方式qopenFileOutput()/写文件qopenFileInput()/读文件q特点:限定文件的保存地点,适合小文件8.2 文件存储n8.2.1 内部存储qopenFileOutput()n如果指定的文件存在,直接打开文件准备写入数据n如果指定的文件不存在,则创建一个新的文件n格式:public FileOutputStream openFileOutput(String name,in
5、t mode)q第1个参数是文件名称,这个参数不可以包含描述路径的斜杠q第2个参数是操作模式,Android系统支持四种文件操作模式 q函数的返回值是FileOutputStream类型8.2 文件存储n8.2.1 内部存储qopenFileOutput文件模式模式模式 说明说明 MODE_PRIVATE 私有模式,缺陷模式,文件仅能够被创建文件的程序访问,或具有相同UID的程序访问。MODE_APPEND 追加模式,如果文件已经存在,则在文件的结尾处添加新数据。MODE_WORLD_READABLE 全局读模式,允许任何程序读取私有文件。MODE_WORLD_WRITEABLE 全局写模式,
6、允许任何程序写入私有文件。8.2 文件存储n8.2.1 内部存储qopenFileInput()n格式:public FileInputStream openFileInput(String name)q参数是文件名称,不允许包含描述路径的斜杠q使用openFileInput()函数打开已有文件,并以二进制方式读取数据的示例代码如下1 String FILE_NAME=fileDemo.txt;2 FileInputStream fis=openFileInput(FILE_NAME);34 byte readBytes=new bytefis.available();5 while(fis.
7、read(readBytes)!=-1)6 8.2 文件存储n8.2.1 内部存储qInternalFileDemo用户界面图8.2 文件存储n8.2.2 外部存储q文件保存于SD卡qMicro SD卡使用FAT文件系统,不支持访问模式和权限控制(安全性低)q适合大容量文件q可以指定SD卡中的文件存放位置q需要SD卡的加载权限与写入权限q文件保存在/mnt/sdcard(sdcard)目录下8.2 文件存储n8.2.2 外部存储qSDcardFileDemo用户界面图8.2 文件存储n8.2.3 资源文件q文件与项目在一起,位于项目/res/raw和/res/xml目录中的原始格式文件和XML
8、文件操作q原始格式文件可以是任何格式的文件,例如视频格式文件、音频格式文件、图像文件或数据文件等等q在应用程序编译和打包时,/res/raw目录下的所有文件都会保留原有格式不变。而/res/xml目录下一般用来保存格式化数据的XML文件,则会在编译和打包时将XML文件转换为二进制格式,用以降低存储器空间占用和提高访问效率,在应用程序运行的时候会以特殊的方式进行访问 q资源文件有专门的类进行操作8.2 文件存储n8.2.3 资源文件qResourceFileDemo示例演示了如何在程序运行时访问资源文件q当用户点击“读取原始文件”按钮时,程序将读取/res/raw/raw_file.txt文件,
9、并将内容显示在界面上,如下图所示8.3 数据库存储n8.3.1 SQLite数据数据库qSQLite是一个2000年由D.Richard Hipp发布的开源嵌入式关系数据库q轻量级数据库SQLite的特点n比传统数据库更适合用于嵌入式系统n占用资源少,运行高效可靠,可移植性强n提供了零配置(zero-configuration)运行模式qSQLite数据库的优势n可以嵌入到使用它的应用程序中n客户端和服务器在同一进程空间运行n简化了数据库的管理过程8.3 数据库存储n8.3.2 手动建库q启动Android虚拟机qAndroidSDK目录/platform-tools/下启动adb shell
10、qLinux命令提示符下输入sqlite3 启动sqliteq常用命令 编号编号命令命令说明说明12.mode MODE?TABLE?设置输入格式13.databases显示数据库名称和文件位置17.quit退出19.schema?TABLE?显示表的创建语句22.tables?PATTERN?显示符合匹配模式的表名8.3 数据库存储n8.3.2 手动建库q创建数据库n命令:Sqlite3 peopleinfon 如果数据库存在则打开,不存在则创建qCreate语句创建表1sqlite create table peopleinfo 2.(_id integer primary key aut
11、oincrement,3.name text not null,4.age integer,5.height float);6sqlite8.3 数据库存储n8.3.2 手动建库q.tables命令,显示当前数据库中的所有表q.schema命令查看建立表时使用的SQL命令1sqlite.tables2poepleinfo3sqlite1sqlite.schema2CREATE TABLE peopleinfo 3(_id integer primary key autoincrement,4name text not null,5age integer,6height float);7sqli
12、te8.3 数据库存储n8.3.2 手动建库1 sqlite insert into peopleinfo values(null,Tom,21,1.81);2 sqlite insert into peopleinfo values(null,Jim,22,1.78);3 sqlite insert into peopleinfo values(null,Lily,19,1.68);q因为_id是自动增加的主键,因此在输入null后,SQLite数据库会自动填写该项的内容_id_idnamenameageageheightheight1Tom211.812Jim221.783Lily191.
13、688.3 数据库存储n8.3.2 手动建库q.mode命令 n支持:column格式,还支持csv格式、html格式、insert格式、line格式、list格式、tabs格式和tcl格式1sqlite.mode column2sqlite select*from peopleinfo;31 Tom 21 1.8142 Jim 22 1.7853 Lily 19 1.686sqlite8.3 数据库存储n8.3.3 代代码操作操作q在Android系统中,每个应用程序的SQLite数据库被保存在各自的/data/data/databases目录下q缺省情况下,所有数据库都是私有的,仅允许创建
14、数据库的应用程序访问,如果需要共享数据库则可以使用ContentProviderqSQLiteOpenHelper,打开数据库qSQLiteDatabase,执行SQL语句,完成数据查询与更新q流程:n创建数据表n打开数据库n插入,更新,删除,查询n关闭数据库8.3 数据库存储n8.3.3 代代码操作操作qSQLiteDemoSQLiteDemo用户界面n8.3.3 代代码操作操作nSQLiteOpenHelper方法qgetReadableDatabase()n会先以读写方式打开数据库,如果磁盘空间满了,数据库打开失败,会以只读打开,如果问题解决,只读对象就会关闭,返回可读写对象qgetWr
15、itableDatabase()n创建或打开一个可以读写的数据库 8.3 数据库存储n8.3.3 代代码操作操作nSQLiteOpenHelper运行机制q如果数据库不存在,调用onCreat(),不调用onUpgrade();q如果数据库存在,但是版本不一样,调用onUpgrade(),不调用onCreate();q如果数据库存在,版本也一样,调用onCreate()和onUpgrade();q当调用getWritableDatabase,getReadableDatabase如果数据库没有打开,就调用onOpen方法,如果打开了就不调onOpen;q 数据库的表的创建一般都在SQLiteO
16、penHelper的onCreat()中,表字段升级,都会在onUpgrade()处理;8.3 数据库存储n8.3.3 代代码操作操作n数据库操作qinsert(String table,String nullColumnHack,ContentValues values)/第二个参数一般第二个参数一般为null,表示允,表示允许插入空插入空值qupdate(String table,ContentValues values,String whereClause,String whereArgs)qdelete(String table,String whereClause,String wh
17、ereArgs)qCursor query(String table,String columns,String selection,String selectionArgs,String groupBy,String having,String orderBy,String limit)qexecSQL()n执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句;qrawQuery()方法用于执行select语句。8.3 数据库存储SQLiteDatabasenquery参数说明位置位置 类型类型+名称名称 说明说明 1String table表名称
18、2String columns返回的属性列名称3String selection查询条件4String selectionArgs如果在查询条件中使用通配符(?),则需要在这里定义替换符的具体内容5String groupBy分组方式6String having定义组的过滤器 7String orderBy排序方式 8.4 数据分享n8.4.1 ContentProviderqAndroid应用程序运行在不同的进程空间中,不同应用程序的数据是不能够直接访问的qContentProvider是应用程序之间共享数据的一种接口机制,可以指定需要共享的数据,而其它应用程序则则可在不知道数据来源、路径的
19、情况下,对共享数据进行查询、添加、删除和更新等操作qContentProvider完全屏蔽了数据提供组件的数据存储方法q调用者无需知道数据提供者的内部数据的存储方法8.4 数据分享n8.4.1 ContentProviderq调用者不能直接调用ContentProvider的接口函数,而需要使用ContentResolver对象,通过URI间接调用ContentProvider,调用关系如下图所示8.4 数据分享n8.4.1 ContentProvider调用qContentResolver对象通过URI确定要访问的ContentProvider数据集qURI是通用资源标志符(Uniform
20、Resource Identifier),用来定位远程或本地的可用资源qContentProvider使用的URI语法结构如下1content:/ncontent:/是通用前缀,表示该URI用于ContentProvider定位资源n授权者,确定哪个ContentProvider提供资源n一般都由类的小写全称组成,以保证唯一性。是数据路径,用来确定请求的是哪个数据集8.4 数据分享n8.4.1 ContentProvider调用q如果请求的数据并不只限于一条数据,则是可以省略,例如n 请求整个people数据集的URI应写为1 content:/edu.hrbeu.peopleprovider
21、/peoplen请求people数据集中第3条数据的URI则应写为1 content:/edu.hrbeu.peopleprovider/people/38.4 数据分享n8.4.2 创建数据提供者ContentProviderq程序开发人员通过继承ContentProvider类可以创建一个新的数据提供者,过程可以分为三步n继承ContentProvider,并重载六个函数n声明CONTENT_URI,实现UriMatchern注册ContentProvider8.4 数据分享n8.4.2 创建数据提供者q1.创建ContentProvider,重载六个函数n新建立的类继承ContentPr
22、ovider后,共有六个函数需要重载,分别是qdelete():删除数据集qinsert():添加数据集qqurey():查询数据集qupdate():更新数据集qonCreate():初始化底层数据集和建立数据连接等工作qgetType():返回指定URI的MIME数据类型如果URI是单条数据,则返回的MIME数据类型应以vnd.android.cursor.item开头如果URI是多条数据,则返回的MIME数据类型应以vnd.android.cursor.dir/开头8.4 数据分享n8.4.2 创建数据提供者q2.声明CONTENT_URI和构造UriMatcher的代码如下1publi
23、c static final String AUTHORITY=edu.hrbeu.peopleprovider;2public static final String PATH_SINGLE=“people/#”;/单条数据路径,#可以代表任何数字3public static final String PATH_MULTIPLE=“people”;/多条数据路径4public static final String CONTENT_URI_STRING=content:/+AUTHORITY+/+PATH_MULTIPLE;5public static final Uri CONTENT_U
24、RI=Uri.parse(CONTENT_URI_STRING);6private static final int MULTIPLE_PEOPLE=1;/返回代码7private static final int SINGLE_PEOPLE=2;89private static final UriMatcher uriMatcher;10static 11uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);12uriMatcher.addURI(AUTHORITY,PATH_SINGLE,MULTIPLE_PEOPLE);13uriMatcher.a
25、ddURI(AUTHORITY,PATH_MULTIPLE,SINGLE_PEOPLE);148.4 数据分享n8.4.2 创建数据提供者qUriMatcher,识别来访者需要调用多条还是单数数据n使用UriMatcher时,则可以直接调用match()函数,对指定的URI进行判断,示例代码如下1 switch(uriMatcher.match(uri)2case MULTIPLE_PEOPLE:3 /多条数据的处理过程4 break;5case SINGLE_PEOPLE:6 /单条数据的处理过程7 break;8default:9 throw new IllegalArgumentExce
26、ption(不支持的URI:+uri);10 8.4 数据分享n8.4.2 创建数据提供者q3.注册ContentProvidern在完成ContentProvider类的代码实现后,需要在AndroidManifest.xml文件中进行注册n注册ContentProvider使用标签,示例代码如下12 4n在上面的代码中,注册了一个授权者名称为edu.hrbeu.peopleprovider的ContentProvider,其实现类是PeopleProvider8.4 数据分享n8.4.3 使用数据提供者q每个Android组件都具有一个ContentResolver对象,获取Content
27、Resolver对象的方法是调用getContentResolver()函数ContentResolver resolver=getContentResolver();8.4 数据分享n8.4.3 使用数据提供者q查询操作n在获取到ContentResolver对象后,程序开发人员则可以使用query()函数查询目标数据n下面的代码是查询ID为2的数据1String KEY_ID=_id;2String KEY_NAME=name;3String KEY_AGE=age;4String KEY_HEIGHT=height;56Uri uri=Uri.parse(CONTENT_URI_STRI
28、NG+/+2;7Cursor cursor=resolver.query(uri,8new String KEY_ID,KEY_NAME,KEY_AGE,KEY_HEIGHT,null,null,null);8.4 数据分享n8.4.3 使用数据提供者q查询操作nContentResolver的query()函数语法结构如下1Cursor query(Uri uri,String projection,String selection,String selectionArgs,String sortOrder)quri定义了查询的数据集qprojection定义了从应返回数据的哪些属性qsel
29、ection定义了返回数据的查询条件qselectArgs,查询参数qsortOrder查询结果排序8.4 数据分享n8.4.3 使用数据提供者q添加操作ninsert()函数,向ContentProvider中添加一条数据nbultInsert()函数,批量的添加数据1ContentValues values=new ContentValues();2values.put(KEY_NAME,Tom);3values.put(KEY_AGE,21);4values.put(KEY_HEIGHT,1.81f);56Uri newUri=resolver.insert(CONTENT_URI,va
30、lues);8.4 数据分享n8.4.3 使用数据提供者q删除操作n使用delete()函数n如果需要删除单条数据,则可以在URI中指定需要删除数据的IDn如果需要删除多条数据,则可以在selection中声明删除条件1Uri uri=Uri.parse(CONTENT_URI_STRING+/+2);2int result=resolver.delete(uri,null,null);n也可以在selection将删除条件定义为ID大于4的数据1String selection=KEY_ID+4;2int result=resolver.delete(CONTENT_URI,selectio
31、n,null);8.4 数据分享n8.4.3 使用数据提供者q更新操作n更新操作需要使用update()函数,参数定义与delete()函数相同,同样可以在URI中指定需要更新数据的ID,也可以在selection中声明更新条件1ContentValues values=new ContentValues();7values.put(KEY_NAME,Tom);8values.put(KEY_AGE,21);9values.put(KEY_HEIGHT,1.81f);23Uri uri=Uri.parse(CONTENT_URI_STRING+/+7);4int result=resolver.update(uri,values,null,null);8.4 数据分享n8.4.4 示例qContentProviderDemo是一个无界面的示例,仅提供一个ContentProvider组件,供其它应用程序进行数据交换n底层使用SQLite数据库,支持数据的添加、删除、更新和查询等基本操作nContentResolverDemo是调用ContentProvider的示例,自身不具有任何数据存储功能,仅是通过URI访问ContentProviderDemo示例提供的ContentProvider。界面如右图所示,该界面基本与示例界面相同
限制150内