Android数据库的操作之存储和获取(转)

Android 数据库的操作

android平台中可以用来存储数据的方式很多,平时常用的有sharedpreference、file存储、sqlite数据库存储以用网络存储几种基本的存储方法。

下面比较详细的介绍如何实现数据的存储和获取:

轻量级的SharedPreferences存储,它是Android提供用来存储一些简单的配置信息的一种机制,例如,一些默认欢迎语、登录的用户名和密码等。其以键值对的方式存储,使得我们可以很方便的读取和存入。这个界面有点类似J2EE平台中的简单的

登陆界面。例如手机平台中游戏或者应用程序登陆之前要输入个人的用户名和密码的数据,我们就可以用SharedPreferences来存储数据。

在我们的上海电信项目中的登录界面就用到sharedPreferences来保存数据。SharedPreferences是通过Context类的getSharedPreferences方法操作的。preferences储存在文件中,而文件名用来指向preferences。

getSharedPreferences(String,int)。在一个类里面实例化,就可以在其它地方共享这些数据。目前这个类不支持多进程使用。

下面的代码是怎么从prefecences中读取数据:

publicstaticfinalStringPREF_FILE_NAME=“PrefFile”;

SharedPreferencespreferences=getSharedPreferences(PREF_FILE_NAME,MODE_PRIVATE);intstoredPreference=preferences.getInt(”storedInt”,0);//usethevalues

其中MODE_PRIVATE是preferences的操作模式,这是默认的模式,代表只有创建这个preferences的程序才能访问这个preferences。其他两个模式是MODE_WORLD_READABL和MODE_WORLD_WRITEABLE:1、MODE_WORLD_READABLE表示其他程序对这个SharedPreferences只有只读权限。

2、MODE_WORLD_WRITEABLE则是其他程序同时拥有读写权限。

ActivityPreferences:

sharedpreferences可以被其他程序的组件使用。但是如果你不需要和其他组件共享preferences,而是希望一个在activities内设一个私有的preferences。可以用activity类的getPreferences()方法来实现。getPreference方法用activity类的名字作为参数调用getSharedPreference()。

上海电信项目中就提供了一个可以供其它程序的组件使用的SharedPreferences,以下是怎么获得SharedPreferences对象的代码:

SharedPreferencessp=this.getPreferences(Context.MODE_PRIVATE);

用SharedPreference.Editor往preference文件中保存数据。Editor是SharedPreference的内部接口。

API中提供了

abstractSharedPreferences.Editoredit()通过这个方法返回一个SharedPrefenences.Editor实例化对象

abstractSharedPreferences.EditorputBoolean(Stringkey,booleanvalue)----设置boolean值存储

abstractSharedPreferences.EditorputFloat(Stringkey,floatvalue)----设置浮点型数据存储

abstractSharedPreferences.EditorputInt(Stringkey,intvalue)----设置整形数据存储

abstractSharedPreferences.EditorputLong(Stringkey,longvalue)----设置长整型abstractSharedPreferences.EditorputString(Stringkey,Stringvalue)---设置字符串数据存储

上海电信项目中我们是通过以下代码来保存用户登录的数据:(在LoginActivity类中)

Editoreditor=sp.edit();

editor.putBoolean("ischecked",checked);//valuetostore

editor.putString("username",checked?username:"");

editor.putString("password",checked?password:"");

editor.commit();

当然我们也可以用SharedPreference.Editor来remove和clear来删除数据。

那我们用SharedPreference保存的在android平台的哪个位置呢?SharedPreference是以xml格式自动保存的,在DDMS中的FileExplorer中展开到/data/data/<packagename>/<projectname>下可以找到一个XXX.xml的文件,在xml文档中保存了设置进去的值。整体效率来看不是特别的高,对于常规的轻量级而言比SQLite要好不少,如果真的存储量不大可以考虑自己定义文件格式。xml处理时Dalvik会通过自带底层的本地XMLParser解析,比如XMLpull方式,这样对于内存资源占用比较好。

文件存储和传统的java文件操作一样,在androidApi中提供了openFileInput和openFileOutput方法来读取设备上的文件。但是在默认状态下,文件是不能在不同的程序之间共享的,以上两个方法只支持读取该应用目录下的文件,读取非其自身目录下的文件将会抛出FileNotFoundException异常。创建的文件存放在/data/data/<packagename>/files目录下。关于文件流的操作是属于J2se的基本知识,这里就不再重复了,不了解的可以看看anroid的API。特别注意一点使用openFileOutput方法创建的文件只能被其调用的应用使用,其他应用无法读取这个文件,如果需要在不同的应用中共享数据,可以使用ContentProvider实现,关于ContentProvider我们将在稍后的内容中介绍。如果我们要用到的一些额外的资源文件,我们可以把这些文件放在应用程序的/raw/raw下,那么就可以在你的应用中使用getResources获取资源后,以openRawResource方法(不带后缀的资源文件名)打开这个文件。

ResourcesmyResources=getResources();

InputStreammyFile=myResources.openRawResource(R.raw.myfilename);

除了前面介绍的读写文件外,Android还提供了诸如deleteFile、fileList等方法来操作文件,不再赘述。

Sqlite数据库存储和ContentProvider对象介绍。

Android应用的另外一个方面:数据存储。用户可以将自己的数据存储到文件系统或者数据库当中,当然最经常的是,用户将自己的数据存储到SQLite数据库当中。SQLite是Android所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。在我们上海电信和joyque电子书项目中sqlite数据库存储和ContentProvider对象是联合在一起使用的。

下面我们来了解ContentProvider和ContentResolver以及ContentProvider和ContentResolver中都用到的URI.

1、ContentProvider对象。因为Android这个系统和其他的操作系统还不太一样,读者需要记住的是,数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。那这个时候有读者就会提出问题,难道两个程序之间就没有办法对于数据进行交换?Android这么优秀的系统不会让这种情况发生的。解决这个问题主要靠ContentProvider。一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。也就是说,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据暴露出去。外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数据,当然,中间也会涉及一些权限的问题。下边列举一些较常见的接口,这些接口如下所示。

query(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder):通过Uri进行查询,返回一个Cursor。

insert(Uriurl,ContentValuesvalues):将一组数据插入到Uri指定的地方。

update(Uriuri,ContentValuesvalues,Stringwhere,String[]selectionArgs):更新Uri指定位置的数据。

delete(Uriurl,Stringwhere,String[]selectionArgs):删除指定Uri并且符合一定条件的数据。

我们可以参考上海电信项目中GamesProvider,joyque电子书项目的ReaderProvider都继承了ContentProvider对象,并且都实现了以上的接口。

2.什么是ContentResolver。外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的ContentResolver实例。ContentResolver提供的接口和ContentProvider中需要实现的接口对应,主要有以下几个。

query(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder):通过Uri进行查询,返回一个Cursor。

insert(Uriurl,ContentValuesvalues):将一组数据插入到Uri指定的地方。

update(Uriuri,ContentValuesvalues,Stringwhere,String[]selectionArgs):更新Uri指定位置的数据。

delete(Uriurl,Stringwhere,String[]selectionArgs):删除指定Uri并且符合一定条件的数据。

在上海电信项目中的SocketService类,我们可以看到service层是怎么更新,插入,删除数据的。

ContentResolverconResolver;

conResolver.insert(Games.GameData.CONTENT_URI,cv);

conResolver.insert(Games.GameTypeData.CONTENT_URI,cv);

conResolver.insert(Games.GameTopicData.CONTENT_URI,cv);

/**

*删除数据

*/

privatevoiddeleteData(){

conResolver.delete(Games.GameTopicData.CONTENT_URI,null,null);

conResolver.delete(Games.GameTypeData.CONTENT_URI,null,null);

conResolver.delete(Games.GameData.CONTENT_URI,Games.GameData.STATE+"!="+Games.GameData.STATE_INSTALLED,null);

}

/**

*更新游戏表中的数据

*@paramgi

*游戏数据

*/

privatevoidupdateGamesItemData(GamesItemgi){

ContentValuescv=gi.toContentValues();

conResolver.update(Uri.withAppendedPath(Games.GameData.CONTENT_URI,

String.valueOf(gi.get_id())),cv,null,null);

}

3.ContentProvider和ContentResolver中用到的Uri。

在ContentProvider和ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据。我们看下面的例子。

content://contacts/people/这个Uri指定的就是全部的联系人数据。

content://contacts/people/1这个Uri指定的是ID为1的联系人的数据。在上边两个类中用到的Uri一般由3部分组成

第一部分是:"content://"。

第二部分是要获得数据的一个字符串片段。最后就是ID(如果没有指定ID,那么表示返回全部)。

由于URI通常比较长,而且有时候容易出错,且难以理解。所以,在Android当中定义了一些辅助类,并且定义了一些常量来代替这些长字符串的使用,例如下边的代码:Contacts.People.CONTENT_URI (联系人的URI)。像上面的Games.GameTopicData.CONTENT_URI、 Games.GameTypeData.CONTENT_URI、Games.GameData.CONTENT_URI 表示游戏分栏,游戏分类,游戏数据的URI。

相关推荐