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);//
删除
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
很类似,只是可能一些语法细节不同,具体这个就不写了,
一下会
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
通用程序一样。
还有更多的用法,只有边用边再搜
了
(四)
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);//
删除
相关文章推荐
- Android25闹钟项目——ArrayAdapter动态添加数据,显示数据,删除数据SharedPreferences存储数据,读取数据
- Android数据持久化存储
- Android基础(二) 文件的读写及数据存储
- Android的数据存储(一)
- Android 数据存储
- android数据存储和访问
- Android进阶#(5/12)独特高效的数据存储——SQLite数据库_Android中的数据库开发
- Android数据存储方式(一)文件
- Android数据存储(一)
- Android数据存储SharedPreferences共享参数
- Android进阶(三) 数据存储之SharedPreference
- Android安卓——数据存储之文件存储
- Android数据存储方案ContentProvider存储数据
- Android中数据存储的几种方法
- Android 数据存储——shared preferences
- android数据存储与访问---文件存储
- Android数据存储-通过SharedPreferences实现记住密码的操作
- Android笔记(四十一) Android中的数据存储——SQLite(三)select
- Android数据存储(二)---Sqlite数据库(上)
- Android_数据存储_File