Android数据的四种存储方式

来源:互联网 发布:绿盾软件 编辑:程序博客网 时间:2024/05/16 12:54

概述:四种数据存储方式:SharePreference、SQLite、Content Provider和File。Android系统中,数据基本都是私有的的,都是存放于“data/data/<包名>”目录下,所以要实现数据共享,正确方式是使用Content Provider。

一、SQLite

嵌入式设备 轻型数据库,存储位置在/data/data/<包名>/databases,只有五种数据类型:
    NULL: 空值
    INTEGER: 整数
    REAL: 浮点数
    TEXT: 字符串
    BLOB: 大数据
BOOLEAN型可以用INTEGER的0和1代替true和false;
DATE类型则可以拥有特定格式的TEXT、REAL和INTEGER的值来代替显示,为了能方便的操作DATE类型,SQLite提供了一组函数。

创建数据库方式有两种:
原生SQLiteDatabase方式和SQLiteOpenHelper子类方式。

SQLiteOpenHelper
主要的三个方法:
1、onCreate()该方法是在你没有安装过(第一次运行)的时候执行,这时可以在这个函数中完成初始的数据表的创建
2、onUpgrade()该方法是在你安装过的情况下,对数据继续更新的时候执行,这时可以在这个函数完成数据库版本升级带来的旧版本的兼容问题,以及数据迁移问题。
3、onDowngrade()该方法是在现逆向降级(如应用由版本号4降级安装版本号为3的包)时必须重写的方法,如果应用降级覆盖安装时没有重写该方法则会崩溃。

onCreate()和onUpgrade()执行时机:
1、如果数据库文件不存在,SQLiteOpenHelper在自动创建数据库后会调用onCreate()方法,在该方法中一般需要创建表、视图等组件。在创建前数据库一般是空的,因此不需要先删除数据库中相关的组件。
2、如果数据库文件存在,并且当前版本号高于上次创建或升级的版本号,SQLiteOpenHelper会调用onUpgrade()方法,调用该方法后会更新数据库的版本号。在onUpgrade()方法中除了创建表、视图等组件外,还需要先删除这些相关的组件,因此,在调用onUpgrade()方法前,数据库是存在的,里面还原许多数据库组建。

二、SharedPreference

本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。存储位置在/data/data/<包名>/shared_prefs
SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。

存储数据步骤如下:
  1、根据Context获取SharedPreferences对象
  2、利用edit()方法获取Editor对象。
  3、通过Editor对象存储key-value键值对数据。
  4、通过commit()方法提交数据。

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

getSharedPreferences (String name, int mode),mode有四个选项:
1、Context.MODE_PRIVATE 只能被本应用程序读、写
2、Context.MODE_WORLD_READABLE 能被其他应用程序读,但不能写
3、Context.MODE_WORLD_WRITEABLE 能被其他应用程序读和写
4、Context.MODE_MULTI_PROCESS sdk2.3多个进程同时读写同一个SharedPreferences时它会检查文件是否修改
  

三、ContentProvider

在不同应用程序之间实现数据共享的一种机制。例如音频,视频,图片和通讯录,一般都可以采用此种方式进行存储。每个Content Provider都会对外提供一个公共的URI(包装成Uri对象),如果应用程序有数据需要共享时,就需要使用Content Provider为这些数据定义一个URI,然后其他的应用程序就通过Content Provider传入这个URI来对数据进行操作。此种方式忽略了底层的数据存储实现,ContentProvider提供了一种统一的通过Uri实现数据操作的方式。 其步骤为:
  1、 在当前应用程序中定义一个ContentProvider
  2、 在当前应用程序的AndroidManifest.xml中注册此ContentProvider
  3、其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据
  
ContentResolver提供了诸如insert(), delete(), query()和update()之类的方法。用于实现对ContentProvider中数据的存取操作。
  Uri是一个通用资源标志符,将其分为A,B,C,D 4个部分:
    A:无法改变的标准前缀,包括;”content://”、”tel://”等。当前缀是”content://”时,说明通过一个Content Provider控制这些数据  
    B:URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。例如;”content://com.test.data.myprovider”
    C:路径,可以近似的理解为需要操作的数据库中表的名字,如:”content://hx.android.text.myprovider/name”中的name
    D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部;

四、File

即常说的文件(I/O)存储方法,常用语存储大数量的数据,但是缺点是更新数据将是一件困难的事情。默认情况下,文件是应用程序私有的,其他应用不能访问。当用户卸载应用程序时这些文件也跟着被删除。存储位置在/data/data/<包名>/files
创建和写入一个内部存储的私有文件:
1、调用Context的openFileOutput()函数,填入文件名和操作模式,它会返回一个FileOutputStream对象。
2、通过FileOutputStream对象的write()函数写入数据。
3、FileOutputStream对象的close ()函数关闭流。

            FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);            fos.write(string.getBytes());            fos.close();

openFileOutput(String name, int mode)
name参数: 用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。
mode参数:用于指定操作模式,分为四种:
Context.MODE_PRIVATE = 0
 为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。
Context.MODE_APPEND = 32768
 该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。 
Context.MODE_WORLD_READABLE = 1
 表示当前文件可以被其他应用读取。
MODE_WORLD_WRITEABLE
 表示当前文件可以被其他应用写入。
  
读取一个内部存储的私有文件:
1、调用openFileInput( ),参数中填入文件名,会返回一个FileInputStream对象。
2、使用流对象的 read()方法读取字节
3、调用流的close()方法关闭流

应用编译时保存静态文件
应该把文件保存在项目的 res/raw/ 目录下,你可以通过 openRawResource()方法去打开它(传入参数R.raw.filename),这个方法返回一个 InputStream流对象你可以读取文件但是不能修改原始文件。

InputStream is = this.getResources().openRawResource(R.raw.filename);

保存内存缓存文件
有时候我们只想缓存一些数据而不是持久化保存,可以使用getCacheDir()去打开一个文件,文件的存储目录( /data/data/包名/cache )是一个应用专门来保存临时缓存文件的内存目录。
 
使用外部存储(sdcard)
添加外部存储访问限权

    <!-- 在SDCard中创建与删除文件权限 -->     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>     <!-- 往SDCard写入数据权限 -->     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

检测外部存储的可用性

//获取外存储的状态String state = Environment.getExternalStorageState();if (Environment.MEDIA_MOUNTED.equals(state)) {    // 可读可写    mExternalStorageAvailable = mExternalStorageWriteable = true;} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {    // 可读} else {    // 可能有很多其他的状态,但是我们只需要知道,不能读也不能写  }

访问外部存储器中的文件

1、如果 API 版本大于或等于8,使用getExternalFilesDir (String type)
  该方法打开一个外存储目录,此方法需要一个类型,指定你想要的子目录,如类型参数DIRECTORY_MUSIC和 DIRECTORY_RINGTONES(传null就是你应用程序的文件目录的根目录)。通过指定目录的类型,确保Android的媒体扫描仪将扫描分类系统中的文件(例如,铃声被确定为铃声)。如果用户卸载应用程序,这个目录及其所有内容将被删除。

例如:File file = new File(getExternalFilesDir(null), “fanrunqi.jpg”);

2、如果API 版本小于 8 (7或者更低),使用getExternalStorageDirectory ()

转载:> http://blog.sina.com.cn/s/blog_4d661a8c010138v7.html

http://blog.csdn.net/amazing7/article/details/51437435

原创粉丝点击