Android | DataStrorage 与 ContentProvider

Android DataStorage And ContentProvider

数据持久化

存储方式
SharedPreferences 在键值对中存储私有原始数据
文件存储-内部存储 在设备内存中存储私有数据
文件存储-外部存储 在共享的外部存储中存储公共数据
SQLite 数据库 在私有数据库中存储结构化数据

SharedPreferences

使用键值对的方式来存储数据,将数据存储到 SharedPreferences 中有以下几种方式:

  • Context.getSharedPreferences(String name, int mode) 方法:第一个参数用于指定 SharedPreferences 文件的名称,如果指定的文件不存在则会创建一个, SharedPreferences 文件都是存放在 /data/data//shared_prefs/ 目录下的,第二个参数用于指定操作模式。
  • Activity.getPreferences(int mode) 方法:接收一个操作模式参数,自动将当前 Activity 的类名作为 SharedPreferences 的文件名。储存数据分三步,第一步调用 SharedPreferences 对象 edit() 方法获取一个对象,第二部利用形如 putString() 的方法向对象中添加数据,第三步调用 apply() 方法将添加的数据提交,完成数据的存储。
  • PreferenceManager.getDefaultSharedPreferences(Context) 方法:以包名加上 _preferences 作为文件名,以 MODE_PRIVATE 模式创建 SP 文件,即 packgeName_preferences.xml

在存储时用到的 SharedPreferences.Editor 中的每一种 put 方法都对应着一个 get 方式去读取数据,接受两个参数,一个是键,另一个是找不到相应键值时返回的默认值。

文件存储

不对存储的内容进行任何格式化处理,所有数据都是原封不动地保存到文件当中。并不适合用于保存一些较为复杂的结构型数据。

Context 类中提供了一个 openFileOutput() 方法,可以用于将数据存储到指定的文件中。这个方法接收两个参数:第一个参数是文件名,在文件创建的时候使用,注意这里指定的文件名不可以包含路径,因为所有的文件都默认存储到 /data/data//files/ 目录下;第二个参数是文件的操作模式,主要有 MODE_PRIVATEMODE_APPEND 两种模式可选,默认是 MODE_PRIVATE ,表示当指定相同文件名的时候,所写入的内容将会覆盖原文件中的内容,而 MODE_APPEND 则表示如果该文件已存在,就往文件里面追加内容,不存在就创建新文件。openFileOutput() 方法返回的是一个 FileOutputStream 对象,得到这个对象之后就可以使用 Java流 的方式将数据写入文件中。

Context 类中还提供了一个 openFileInput() 方法,用于从文件中读取数据,接收一个参数,即要读取的文件名,然后系统会自动到 /data/data//files/ 目录下加载这个文件并返回一个 FileInputStream 对象,得到这个对象之后,再通过流的方式就可以将数据读取出来。

SQLite 数据库存储

Android 提供了一个 SQLiteOpenHelper 帮助类,借助这个类可以非常简单地对数据库进行创建和升级。SQLiteOpenHelper 中有两个抽象方法:onCreate()onUpgrade()。我们必须在自己的帮助类里重写这两个方法,然后分别在这两个方法中实现创建和升级数据库的逻辑。SQLiteOpenHelper 中还有两个非常重要的实例方法:getReadableDatabase()getWritableDatabase() 。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则要创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。

SQLite 支持的数据类型包括:integer 表示整型,real 表示浮点型,text 表示文本类型,blob 表示二进制类型。primary key 关键字设置主键。

Android 支持直接通过 SQL 来进行数据的增删查改,还提供了简单的辅助方式进行CRUD操作

  • insertSQLiteDatabase 中提供了一个 insert() 方法,专门用于添加数据。它接收3个参数:第一个参数是表名;第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值 NULL ;第三个参数是一个 ContentValues 对象,它提供了一系列的 put() 方法重载,用于向 ContentValues 中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。
  • deleteSQLiteDatabase 中提供了一个 delete() 方法,专门用于删除数据。这个方法接收3个参数:第一个参数是表名;第二、第三个参数用于约束删除某一行或某几行的数据,不指定的话默认会删除所有行。
  • selectSQLiteDatabase 中提供了一个 query() 方法用于对数据进行查询,需要的参数很多,在下表中列出并与 SQL 做出比较。
  • updateSQLiteDatabase 中提供了一个 update() 方法,用于对数据进行更新。这个方法接收4个参数:第一个参数是表名,指定更新哪张表里的数据;第二个参数是 ContentValues 对象,要把更新数据在这里组装进去;第三、第四个参数用于约束更新某一行或某几行中的数据,不指定的话默认会更新所有行。
query()方法 SQL方法
table from table_name 指定查询的表名
columns select column1, column2 指定查询的列名
selection where column = value 指定where的约束条件
selectionArgs - 为where中的占位符提供具体的值
groupBy group by column 指定需要group by的列
having having column = value 对group by后的结果进一步约束
orderBy order by column1, column2 指定查询结果的排序方式

ContentProvider 概念

主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。

访问其他程序中数据

对于每一个应用程序来说,如果想要访问 ContentProvider 中共享的数据,就一定要借助 ContentResolver 类,可以通过 Context 中的 getContentResolver() 方法获取该类的实例。ContentResolver 中提供了一系列的方法用于对数据进行增删改查操作,其中 insert() 方法用于添加数据,update() 方法用于更新数据,delete() 方法用于删除数据,query() 方法用于查询数据。

// 外部进程 向 ContentProvider 中添加数据 
public Uri insert(Uri uri, ContentValues values); 

// 外部进程 删除 ContentProvider 中的数据 
public int delete(Uri uri, String selection, String[] selectionArgs);

// 外部进程 更新 ContentProvider 中的数据 
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); 

// 外部应用 获取 ContentProvider 中的数据 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);

这4个方法由外部进程回调,并运行在 ContentProvider 进程的 Binder线程池 中(不是主线程).

通过 URI(统一资源标识符) 分别不同App,协议名为 content 。“主机名”为包名,路径为需要访问的数据库表。

/**
[协议名]://[用户名]:[密码]@[主机名]:[端口]/[路径]?[查询参数]#[片段ID]

content://com.example.app.provider/table1
*/

URI uri = URI.parse("content://com.example.app.provider/table1");

总体使用逻辑如下:

URI uri = URI.parse("content://com.example.app.provider/table1"); 
ContentResolver resolver = context.getContentResolver(); 
ContentValues values = new ContentValues(); 
values.put("_id", 1); 
values.put("name", "values1"); 
resolver.insert(uri, values);

创建 ContentProvider

如果想要实现跨程序共享数据的功能,可以通过新建一个类去继承 ContentProvider 的方式来实现。ContentProvider 类中有6个抽象方法,我们在使用子类继承它的时候,需要将这6个方法全部重写。

// 外部进程 向 ContentProvider 中添加数据 
public Uri insert(Uri uri, ContentValues values); 

// 外部进程 删除 ContentProvider 中的数据 
public int delete(Uri uri, String selection, String[] selectionArgs);

// 外部进程 更新 ContentProvider 中的数据 
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); 

// 外部应用 获取 ContentProvider 中的数据 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder);

// ContentProvider 创建后或打开系统后其它进程第一次访问该 ContentProvider 时,由系统进行调用 
public boolean onCreate();

// 得到数据类型,即返回当前 Url 所代表数据的 MIME 类型 
public String getType(Uri uri) { 
	//在此匹配URI 
	URIMatcher.match(uri)}

在注册创建的 ContentProvider 时需要将授权信息填写到 AndroidManifest

<provider 
	android:name="MyProvider" 
	android:authorities="com.example.mycontentprovider" 
/>

你可能感兴趣的:(Android,android,数据库,sqlite)