欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android数据的四种存储方式

程序员文章站 2022-05-15 22:37:20
...

概述:四种数据存储方式: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

相关标签: android 数据库