您的位置:首页 > 移动开发 > Android开发

Android数据存储

2009-10-21 14:20 447 查看

Android

中,提供了三种数据存储的途径,和两种存储方式。

三种途径:


l

系统配置
(
Shared Preferences

)



这类应用主要是系统的配置信息的保存,比如我给程序界面设置了颜色,我想在下一次启动时还是能够保留上次设置的颜色。由于
Android

系统的界面是采用
Activity

栈的形式,在系统资源不足时,会收回一些界面,那么,我想有些操作也是需要在不活动时保留下来的,等再次激活时能够显示出来。

l

文件(
Files



Android

是一个操作系统,自然而然对存储系统会有一个管理,因为采用提
Linux

核心,所有在
Andorid

系统中,文件也是
Linux

的形式。当然我们的应用程序也就可以把数据以文件的形式记录下来咯。

l

数据库(
SQLite Databases




Andriod

系统中,也少不了一个数据库管理,但考虑到系统资源(内存,硬盘),选择了轻便型的数据库
SQLite

,这是一个开源的关系型数据库,与普通关系型数据库一样,也具有
ACID

的特性。

两种存储方式:


主要是根据数据库共享方式来分

l

程序内自用:

通常我们程序中需要的数据一般都是为本程序来用,所以我们用上面三种途径来创建的程序都是默认为本程序使用,其他程序无法获取操作。

我们
ADB

插件功能在命令行下输入:
adb shell

来进入手机的文件系统,进入
CD /data/data

目录。然后
ls

查看,我们发现,我们在系统中安装的每个程序在这里都有一个文件夹,再次进入我们的程序后
ls

查看,会出现几个目录:
shared_prefs


files


databases

,这几个目录其实就是存的我们程序内自用的数据,内容分别就是由上面三种途径创建的,当然如果没有创建过,这个目录可能不存在。

l

数据需要共享:

这类数据通常是我们的一些共用数据,很多程序都会来调用,比如电话薄数据,就不可能存为私有的了。当然,这种方式的话,上面三种途径中的系统配置就不适用了,“系统配置”只能由本程序访问。也就是说,只有文件和数据库可以共享。

具体用没我们下面依次试一下:


(一)

系统配置

这类数据存储形式是
NVP

形式即,
name


value

的映射
map



存:


//
取得活动的
preferences
对象
.

SharedPreferences uiState = getPreferences(0);

//
取得编辑对象

SharedPreferences.Editor editor = uiState.edit();

//
添加值

editor.putString(
KEY

,
value
);

editor.putBoolean(
KEY

,
value
);

editor.commit();
//
提交保存
.

取:


//
取得活动的
preferences
对象
.

SharedPreferences settings = getPreferences(Activity.
MODE_PRIVATE

);

//
取得值
.

String value = settings.getString(
KEY

,
"
默认值
"
);

Boolean value = settings.getBoolean(
KEY

,
false

);

存取时间:


有了存取的方法后,我们就要想在什么时候来存取:

protected void onPause()/

/
系统通知暂停,可以保存设置

public void onDestroy()/

/
系统通知关闭,可以保存设置

public void onCreate(Bundle savedInstanceState) /

/
系统启动,可以打开设置

同样还有其他状态,我们可以根据实际情况来处理

(二)

文件操作

l

打开文件并可操作,如果文件不存在会自动创建:

FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);

//

操作时,在
fos

里写入值即可

l

读文件:

FileInputStream fis = openFileInput(FILE_NAME);

l

取得当前活动创建的文件列表:

String[] lst =fileList()

l

删除文件:

super.deleteFile(FILE_NAME);

(三)

SQLite

数据库操作

数据库操作无非是建库、建表、增、删、改、查的一些常用功能。在
Android

系统中封装了一个
SQLiteDatabase

类,用于这些操作。

l

建库


创建数据库,是由
SQLiteOpenHelper

类自动完成,同时,创建后,会返回一个
SQLiteDatabase

类:

try {

SQLiteOpenHelper dbHelper= new SQLiteOpenHelper(context,

DBName,

null,1);

db = dbHelper.getWritableDatabase();

} catch (SQLiteException ex) {

db = dbHelper.getReadableDatabase();

}

其中参数
DBName

就是数据库的名称。
getWritableDatabase()

,这方法就会获取数据库对象,如果库不存在就会新建,但这里为什么还要包一层
catch

呢,主要考虑到,手机的资源有限,有时空间不足了,就无法再写入数据,但这里我们可以读啊,所以在
catch

中调用了
getReadableDatabase



l

建表


_db.execSQL(


create table tableName (id integer primary key autoincrement,name text not null);


);

看到,这个建表其实跟我们写的
SQL

很类似,只是可能一些语法细节不同,具体这个就不写了,
google

一下会
N

多了。

l




当然我们可以执行一条
SQL

语句来插入,我们也可以这样来:

ContentValues newTaskValues =
new

ContentValues();

// Assign values for each row.

newTaskValues.put(
KEY_TASK

, value);

newTaskValues.put(
KEY_CREATION_DATE

, value);

// Insert the row.

db
.insert(
DATABASE_TABLE

,
null

, newTaskValues);

我们可以将值依次放入一个
Hash

表中,然后直接存入。

l




db.delete(

tableName

, "id=" + _rowIndex, null)

输入表名,以及条件,当然,直接拼成一条标准
SQL

也是可以的。

l




ContentValues newValue =
new

ContentValues();

newValue.put(
KEY_TASK

, _task);

db
.update(
DATABASE_TABLE

, newValue,

KEY_ID

+
"="
+ _rowIndex,
null


将值存于
Hash

表中,再直接调用

l




Cursor result =db.query(DATABASE_TABLE,

new String[] { KEY_ID, KEY_TASK, KEY_CREATION_DATE},

null,

条件
, null, null, null)

这里,查询后返回的是一个游标,我们可以通过这游标来获取数据,使用方法跟
java

通用程序一样。

还有更多的用法,只有边用边再搜
Google



(四)

Content Providers

共享数据

在前面界面交互中,我们也学习到了,
Android

系统的界面互相调用时,传值是采用
Uri

的方式进行的。表面上看,
Uri

不就是一个字符串吗,能传多少值啊,其实不然,在
Uri

中格式:
(1)://(2)/(3)

,这第一段我们不管,这第二段,其实在系统中是可以定义到我们的
Content Providers

的,我们可以写一个类,比如这个用来管理电话薄信息,如:

public


class

MyProvider
extends

ContentProvider {

private


static


final

String
myURI

=

"content://com.zjf.MyProvider/items"
;

public


static


final

Uri
CONTENT_URI

= Uri.parse
(
myURI

);




}

在这里
MyProvider
继承了
ContentProvider

,然后我们在系统中注册一下(在
manifext.xml
中):

<provider android:name=


MyProvider


android:authorities=


com.zjf.MyProvider


/>

然后我们在传值时使用:
content://

com.zjf.MyProvider/1
来通过这个
Uri

我想得到电话薄中第一个人的信息,我们分析一下,这个最后一段“
1

”,就是第一个记录咯,“
com.zjf.MyProvider

这个就是标记我用哪一套程序来取数据,所以说,我们写的
MyProvider
就可以根据传入的“
1

”这个参数来进行数据的操作,这里你可以保存到文件中,也可以保存到数据库中,但对使用者来说是透明的,不需要知道内部细节。这就是我们说的数据共享模型。

我们进一步看
MyProvider
继承处理了哪些类:

@Override

public

Cursor query(Uri uri, String[] projection, String selection,

String[] selectionArgs, String sortOrder) {

@Override

public


int

delete(Uri uri, String selection, String[] selectionArgs)

@Override

public

Uri insert(Uri uri, ContentValues values)

@Override

public


int

update(Uri uri, ContentValues values, String selection,

String[] selectionArgs)

看到这些大家可能就更家明白了
MyProvider
就是一个数据的封装,它按照统一的接口来提供共享的数据,每一个
Provider

就是处理一类共享数据。

当然系统中其实己经供了这样的一些
Provider

供我们来使用,比如:
Browser

记录了用户浏览记录;

CallLog

记录系统日志;

Contacts

电话薄;

Settings

系统设置等。


看到这个不知大家有没有想到我们前面取得电话薄信息时是不是用的“
content:// Contacts/1

”这样的
Uri

,对应起来咯。

看了具体的
Provider

的实现,我们又想到,那这个统一的数据接口标准到底能提供我们哪些功能呢,其实看了
Provider

内部实现,我们也发现了,不就也就是增、删、改、查么。对,我们可能通过统一的接口来对这公用数据进行这些操作。具体方法如下:

查询:


Cursor someRows = getContentResolver().query(MyProvider.CONTENT_URI,

null, where, null, order);

插入:


// Create a new row of values to insert.

ContentValues newValues = new ContentValues();

newValues.put(COLUMN_NAME, newValue);

Uri myRowUri = getContentResolver().insert(MyProvider.CONTENT_URI,newValues);

删除:


getContentResolver().delete(MyProvider.CONTENT_URI, where, null);

修改:


getContentResolver().update(MyProvider.CONTENT_URI, newValues, where,

null);

这些几个功能可以有点难理解,我们看个应用吧:

我想查询电话薄中姓陈的人的信息,然后再删除:

Cursor someRows = getContentResolver().query(


content:// Contacts


,

null,


name like

‘陈
%

’”
, null, order);

//

然后从游标中获取数据即可。

getContentResolver().delete(


content:// Contacts


,


name like

‘陈
%

’”
, null);//

删除
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: