当前位置: 代码迷 >> SQL >> Android四种储存方式: sharedpreference,file,SQlite,contentprovider
  详细解决方案

Android四种储存方式: sharedpreference,file,SQlite,contentprovider

热度:118   发布时间:2016-05-05 12:11:28.0
Android四种存储方式: sharedpreference,file,SQlite,contentprovider。

Android四种存储方式: sharedpreference,file,SQlite,contentprovider。

1、SharedPreferences是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data/<包名>/shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的步骤如下:

  一、根据Context获取SharedPreferences对象

  二、利用edit()方法获取Editor对象。

  三、通过Editor对象存储key-value键值对数据。

  四、通过commit()方法提交数据。

  具体实现代码如下:实现存储,读取,清除,删除

效果图:

首先创建:// 首先拿到sharedpreference对象

????? mShared =getSharedPreferences(SHARED_MAIN_XML,?MODE_PRIVATE);

存储:?

复制代码
private?void?write()?{//?存入数据
??????savename?=?name.getText().toString().trim();
??????saveage?=?Integer.valueOf(age.getText().toString().trim());
??????Editor?editor?=?mShared.edit();
??????editor.putString("name",?savename);
??????editor.putInt("age",?saveage);
??????//?保证操作的事务完整性
??????editor.commit();
???}
复制代码
阅读:
private?String?read()?{//?从数据库里读取数据
??????namecontent?=?mShared.getString("name",?"数据库里没有存储姓名");
??????agecontent?=?mShared.getInt("age",?0);
??????String?reading?=?"姓名:"?+?namecontent?+?"\n年龄:"?+?agecontent;
??????return?reading;
???}
清除内容:
复制代码
private?void?clear()?{//清除内容
??????/**?开始清除SharedPreferences中保存的内容?**/
??????Editor?editor?=?mShared.edit();
??????editor.remove("name");
??????editor.remove("age");
??????editor.commit();
?
???}
复制代码
删除文件:
复制代码
private?void?delete()?{//删除文件
??????/**?删除SharedPreferences文件?**/
??????Filefile?=?new?File("/data/data/cn.csdn.activity"?+?"/shared_prefs/"
????????????+?SHARED_MAIN_XML?+?".xml");
??????if?(file.exists())?{
?????????file.delete();
?????????Toast.makeText(this,?"删除成功",?Toast.LENGTH_LONG).show();
??????}
???}
复制代码

haredPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。

2、 File:?即常说的文件(I/O)存储方法,常用存储大数量的数据,但是缺点是更新数据将是一件困难的事情。

下面实现:在本地data文件下使用自己生成的文件处理数据的新建储存 读取 删除

如果说不想把内容存在SharedPreferences中的话,我们可以自己写一个文件保存须要的数据,在这里我将文件保存在系统中的工程路径下。

跟上面布局一样,删除文件也一样,清除内容也查不多,下面只是简单的写和读的方法:

写:

复制代码
String?nameage="名字:"+name.getText().toString().trim()+"年龄:"+age.getText().toString();
??????try?{
?????????os?=?this.openFileOutput(SHARED_MAIN_XML,?MODE_PRIVATE);
?????????/*?把字符串转换成字节数组,写入文件中?*/
?????????os.write(nameage.getBytes());
??????}?catch?(FileNotFoundException?e)?{
?????????e.printStackTrace();
??????}?catch?(IOException?e)?{
?????????e.printStackTrace();
??????}finally?{
?????????try?{
????????????/*?关闭文件输出流?*/
????????????os.close();
?????????}?catch?(IOException?e)?{
????????????e.printStackTrace();
?????????}
??????}
复制代码

?

读:
复制代码
private?String?read()?{
??????String?nameage="";
??????//?打开文件输入流,
??????try?{
?????????is?=?this.openFileInput(SHARED_MAIN_XML);
?????????/*?初始化字节数组?*/
?????????b?=?new?byte[1024];
?????????/*?从文件输入流中读取内容到字节数组中,返回内容长度?*/
?????????int?length?=?is.read(b);
?????????/*?把字节数组转换成字符串?*/
?????????nameage=?new?String(b);
??????}?catch?(FileNotFoundException?e)?{
?????????e.printStackTrace();
??????}?catch?(IOException?e)?{
?????????e.printStackTrace();
??????}
??????return?nameage;
???}
复制代码

很简单吧!!

3、 SQLite是一种转为嵌入式设备设计的轻型数据库,其只有五种数据类型,分别是:

    NULL: 空值

    INTEGER: 整数

    REAL: 浮点数

    TEXT: 字符串

    BLOB: 大数据

它是一个轻量级的数据库、非常小 、 移植性好、效率高、可靠

在Android系统中提供了android.database.sqlite包,用于进行SQLite数据库的增、删、改、查工作。

创建与删除数据库

封装一个类去继承SQLiteOpenHelper? 在构造函数中传入数据库名称与数据库版本号,数据库被创建的时候会调用onCreate(SQLiteDatabase db) 方法,数据库版本号发生改变的时候会调用onUpgrade(SQLiteDatabase db, int oldVersion, intnewVersion)方法,可以方便的对软件游戏升级后做出相应处理避免覆盖安装数据库发生改变产生的错误。调用SQLiteOpenHelper? 的getReadableDatabase()方法去创建数据库,如果数据库不存在则创建并且返回SQLiteDatabase对象,如果数据库存在则不创建只返回SQLiteDatabase对象。调用 deleteDatabase(DATABASE_NAME)方法 传入数据库名称则可删除数据库。

第一种:详细请看上一遍博客:

android之利用SQLite数据库实现登陆和注册


http://greatverve.cnblogs.com/archive/2011/12/26/android-sqlite-login.html

下面介绍第二种:另一种添删改查操作

效果图:

布局文件很简单,在此不再给出!!

直接给创建数据库和表,增删改查的代码:

复制代码
public?class?UserService?{
???private?DatabaseHelper?helper;
?
???public?UserService(Context?context,?String?name,?int?version)?{
??????helper?=?new?DatabaseHelper(context,?name,?version);
???}
???public?UserService(Context?context,?String?name)?{
??????helper?=?new?DatabaseHelper(context,?name);
???}
?
???public?void?insert(UserDao?user)?{//?插入数据
??????SQLiteDatabase?sdb?=?helper.getWritableDatabase();
??????ContentValues?values?=?new?ContentValues();
??????values.put("username",?user.getUsername());
??????values.put("password",?user.getPassword());
??????sdb.insert("user",?"name",?values);
?
??????sdb.close();
???}
?
???public?void?delete(int?id)?{//?删除数据
??????SQLiteDatabase?sdb?=?helper.getWritableDatabase();
??????sdb.delete("user",?"id=?",?new?String[]{String.valueOf(id)});
??????sdb.close();
???}
?
???public?void?update(UserDao?user,?int?id)?{//?更新数据
??????SQLiteDatabase?sdb?=?helper.getWritableDatabase();
??????ContentValues?values=new?ContentValues();
??????values.put("username",?user.getUsername());
??????values.put("password",?user.getPassword());
??????sdb.update("user",?values,?"id=?",?new?String[]{String.valueOf(id)});
??????sdb.close();
???}
?
???public?Cursor?select()?{//?查询所有数据
??????SQLiteDatabase?sdb?=?helper.getWritableDatabase();?????
??????return????sdb.query("user",?new?String[]{"id?as?_id","username","password"},?null,?null,?null,?null,?null);
???}
???public?UserDao?find(int?id){//按id查询数据
??????UserDao?user=null;
??????SQLiteDatabase?sdb=helper.getWritableDatabase();
??????Cursor?cursor=sdb.query("user",?new?String[]{"id","username","password"},?"id=?",?new?String[]{String.valueOf(id)},?null,?null,?null);???
??????if(cursor.moveToFirst()){
?????????user=new?UserDao();
?????????user.setId(cursor.getInt(0));
?????????user.setUsername(cursor.getString(1));
?????????user.setPassword(cursor.getString(2));
??????}
??????cursor.close();
??????sdb.close();
??????return?user;
???}
}
复制代码

?

?

?

插入数据:通过insert(String table, StringnullColumnHack, ContentValues values)方法插入数据,其中参数含义分别为:

    table: 目标表名

    nullColumnHack:?指定表中的某列列名。因为在SQLite中,不允许不允许插入所有列均为null的记录,因此初始值有值为空时,此列需显式赋予null

    values:ContentValues对象,类似于java中的Map。以键值对的方式保存数据。

修改数据: update(String table,ContentValues values, String whereClause, String[] whereArgs)方法用于修改数据,其四个参数的具体含义如下:

    table: 目标表名

    values:?要被修改成为的新值

    whereClause:where子句,除去where关键字剩下的部分,其中可带?占位符。如没有子句,则为null。

    whereArgs: 用于替代whereClause参数中?占位符的参数。如不需传入参数,则为null。

查询数据:query()方法用SELECT 语句段构建查询。SELECT 语句内容作为 query() 方法的参数,比如:要查询的表名,要获取的字段名,WHERE 条件,包含可选的位置参数,去替代 WHERE 条件中位置参数的值,GROUP BY 条件,HAVING 条件。

除了表名,其他参数可以是 null。所以,以前的代码段可以可写成:

?String[] columns={"ID","inventory"};

?String[] parms={"snicklefritz"};

?Cursor result=db.query("widgets",columns, "name=?",parms, null, null, null);

使用游标

不管你如何执行查询,都会返回一个 Cursor,这是 Android 的 SQLite 数据库游标,使用游标,你可以:

通过使用 getCount() 方法得到结果集中有多少记录;

通过 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍历所有记录;

通过 getColumnNames() 得到字段名;

通过 getColumnIndex() 转换成字段号;

通过 getString(),getInt() 等方法得到给定字段当前记录的值;

通过 requery() 方法重新执行查询得到游标;

通过 close() 方法释放游标资源;

删除数据:删除数据也是一件很简单的事,只需要调用delete方法,传入参数即可,delete(String table, String whereClause,String[] whereArgs)的参数三个参数具体含义如下:

    table: 目标表名

    whereClause:where子句,除去where关键字剩下的部分,其中可带?占位符。如没有子句,则为null。

    whereArgs: 用于替代whereClause参数中?占位符的参数。如不需传入参数,则为null。

4、contentprovider

ContentProvider概念

1、? ContentProvider提供为存储和获取数据提供了统一的接口;

2、? 使用ContentProvider可以在不同的应用程序之间共享数据

3、? Android为常见的一些数据提供了ContentPrivider(包括音频,视频,图片和通讯录等等)

ContentProvider使用表的形式来组织数据

Uri

1、? 每一个ContentProvider都拥有一个公共的uri,这个uri用于表示这个ContentProvider所提供的数据

2、? Android所提供的ContentProvider都存放在android.provider包当中

Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:

1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://。

2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。

3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:

要操作contact表中id为10的记录,可以构建这样的路径:/contact/10

要操作contact表中id为10的记录的name字段, contact/10/name

要操作contact表中的所有记录,可以构建这样的路径:/contact

要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:

要操作xml文件中contact节点下的name节点,可以构建这样的路径:/contact/name

如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:

Uriuri =Uri.parse("content://com.changcheng.provider.contactprovider/contact")

?

ContentProvider所提供的函数:

1、? query():查询

2、? insert():插入

3、? update():更新

4、? delete():删除

5、? getType():得到数据类型

6、? onCreate():创建时的回调函数

实现ContentProvider的过程

1、? 定义一个CONTENT_URI常量

2、? 定义一个类,继承ContentProvider

3、? 实现query,insert,update,delete,getType,onCreate方法

4、? 在AndroidManifest.xml当中进行声明

下面是实现代码:

首先创建继承contentprovider的类UserContentProvider?.java

复制代码
public?class?UserContentProvider?extends?ContentProvider?{
???private?DatabaseHelper?helper;
???private?SQLiteDatabase?db;
???private?static?UriMatcher?matcher?=?new?UriMatcher(UriMatcher.NO_MATCH);
???private?static?final?int?USERS?=?1;
???private?static?final?int?USER?=?2;
???static{
??????matcher.addURI("cn.csdn.activity.providers.userprovider",?"user",?USERS);
??????matcher.addURI("cn.csdn.activity.providers.userprovider",?"user/#",?USER);
???}
???public?int?delete(Uri?uri,?String?selection,?String[]selectionArgs)?{
??????db=helper.getWritableDatabase();
??????int?num=0;
??????switch(matcher.match(uri)){
??????case?USERS:
?????????num=db.delete("user",?selection,?selectionArgs);
?????????break;
??????case?USER:
?????????long?id=ContentUris.parseId(uri);
?????????String?where="id="+id;
?????????if(selection!=null&&!"".equals(selection)){
????????????where=where+"?and"+selection;
?????????}
?????????num=db.delete("user",?where,?selectionArgs);
?????????break;
??????default:
?????????throw?new?IllegalArgumentException("Unknown?Uri:"+?uri);
??????}
??????return?num;
???}
?
???public?String?getType(Uri?uri)?{
??????switch(matcher.match(uri)){
??????case?USERS:
?????????return?"vnd.android.cursor.dir/person";
??????case?USER:
?????????return?"vnd.android.cursor.item/person";
??????default:
?????????throw?new?IllegalArgumentException("Unknown?Uri:"+?uri);
??????}
???}
?
???public?Uri?insert(Uri?uri,?ContentValues?values)?{
??????db=helper.getWritableDatabase();
??????long?rowid;
??????switch(matcher.match(uri)){
??????case?USERS:?//向表中添加新纪录并返回其行号
?????????rowid=db.insert("user",?"id",?values);
?????????return?ContentUris.withAppendedId(uri,?rowid);
??????default:
?????????throw?new?IllegalArgumentException("Unknow?Uri:"?+?uri);
??????}????
???}
?
???public?boolean?onCreate()?{
??????helper=new?DatabaseHelper(this.getContext(),"users.db");
??????return?true;
???}
?
???public?Cursor?query(Uri?uri,?String[]?projection,?Stringselection,
?????????String[]?selectionArgs,?String?sortOrder)?{
??????db?=?helper.getReadableDatabase();
??????switch(matcher.match(uri)){
??????case?USERS:
?????????return?db.query("user",?projection,?selection,?selectionArgs,?null,?null,?sortOrder);
??????case?USER:
?????????long?id=ContentUris.parseId(uri);
?????????String?where="id="+id;
?????????if(selection!=null&&!"".equals(selection)){
????????????where=where+"?and"+selection;
?????????}
?????????return?db.query("user",?projection,?where,?selectionArgs,?null,?null,?sortOrder);
??????default:
?????????throw?new?IllegalArgumentException("Unknown?Uri:"+?uri);
??????}
???}
?
???public?int?update(Uri?uri,?ContentValues?values,?String?selection,
?????????String[]?selectionArgs)?{
??????db=helper.getWritableDatabase();
??????int?num;
??????switch(matcher.match(uri)){
??????case?USERS:
?????????num=db.update("user",?values,?selection,?selectionArgs);
?????????break;
??????case?USER:
?????????long?id=ContentUris.parseId(uri);
?????????String?where="id="+id;
?????????if(selection!=null&&!"".equals(selection)){
????????????where=where+"?and"+selection;
?????????}
?????????num=db.update("user",?values,?selection,?selectionArgs);
?????????break;
??????default:
?????????throw?new?IllegalArgumentException("Unknow?Uri"+uri);
??????}
??????return?num;
???}
}
配置manifest.xml:
需要在<application></application>中为provider进行注册!!!!
provider?android:authorities="cn.csdn.activity.providers.userprovider"
????????????android:name="UserContentProvider"></provider>
最后写测试类:
//contentprovider测试
???public?void?testinsert(){//插入数据
??????ContentResolver?resolver?=?this.getContext().getContentResolver();
??????Uri?inserturi=Uri.parse("content://cn.csdn.activity.providers.userprovider/user");
??????ContentValuesvalues=new?ContentValues();
??????values.put("username",?"renhiali");
??????values.put("password",?"123");
??????Uri?uri=resolver.insert(inserturi,?values);
??????Log.i("TAG",?uri.toString());
???}
???public?void?testdelete(){//删除数据
??????ContentResolver?resolver?=?this.getContext().getContentResolver();
??????Uri?deleteuri=Uri.parse("content://cn.csdn.activity.providers.userprovider/user/7");
??????int?num=resolver.delete(deleteuri,?null,?null);
??????Log.i("TAG",?num+"");
???}
???public?void?testupdate(){//更新数据
??????ContentResolver?resolver?=?this.getContext().getContentResolver();
??????Uri?uri=Uri.parse("content://cn.csdn.activity.providers.userprovider/user/8");
??????ContentValuesvalues=new?ContentValues();
??????values.put("username",?"123");
??????resolver.update(uri,?values,?null,?null);
???}
???public?void?testquery(){//查询数据
??????ContentResolver?resolver?=?this.getContext().getContentResolver();
??????Uri?uri=Uri.parse("content://cn.csdn.activity.providers.userprovider/user/4");
??????Cursor?cursor=resolver.query(uri,?null,?null,?null,?null);
??????cursor.moveToFirst();
??????Log.i("TAG",cursor.getString(1));
??????cursor.close();
???}
复制代码转载自:http://www.cnblogs.com/greatverve/archive/2011/12/27/android-sharedpreference-file-SQlite-contentprovider.html
  相关解决方案