1.第 6 章 数据存储全方案
文件存储、SharedPreference 存储以及数据库存储
文件存储:
文件存储的方式并不适合用于保存一些较为复杂的文本数据,所有的文件都是默认存储到/data/data/
SharedPreferences 存储:
保存一些简单的数据和键值对。
不同于文件的存储方式,SharedPreferences 是使用键值对的方式来存储数据的。支持多种不同的数据类型存储.SharedPreferences 文件都是存放在/data/data/
SQLite 数据库存储:
比如我们手机的短信程序中可能会有很多个会话,每个会话中又包含了很多条信息内容,并且大部分会话还可能各自对应了电话簿中的某个联系人。
数据库文件会存放在/data/data/
2.第 7 章 跨程序共享数据,探究 内容提供器
我们学了 Android 数据持久化的技术,包括文件存储、SharedPreferences 存储、以及数据库存储。不知道你有没有发现,使用这些持久化技术所保存的数据都只能在当前应用程序中访问。
不过一些可以让其他程序进行二次开发的基础性数据,我们还是可以选择将其共享的。例如系统的电话簿程序,它的数据库中保存了很多的联系人信息,如果这些数据都不允许第三方的程序进行访问的话,恐怕很多应用的功能都要大打折扣了。除了电话簿之外,还有短信、媒体库等程序都实现了跨程序数据共享的功能,而使用的技术当然就是内容提供器了。
1)一种是使用现有的内容提供器来读取和操作相应程序中的数据,
通过Context 中的 getContentResolver()方法。ContentResolver 中提供了一系列方法用于对数据进行 CRUD增删改 操作,
类似SQLite 数据库存储的SQLiteDatabase增删改接口,不同是不接收表名参数,而是使用一个 Uri 参数代替。
content://com.example.app.provider/table1
协议声明 包名加provider组成权限 表名
2)另一种是创建自己的内容提供器给我们程序的数据提供外部访问接口。
那些提供外部访问接口的应用程序都是如何实现这种功能的呢?它们又是怎样保证数据的安全性,使得隐私数据不会泄漏出去?
新建一个类去继承 ContentProvider 的方式来创建一个自己的内容提供器。(ContentProvider 类中有六个抽象方法,我们在使用子类继承它的时候,需要将这六个方法全部重写。)
在这六个方法中,相信大多数你都已经非常熟悉了,我再来简单介绍一下吧。
1. onCreate()
初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,
返回 true 表示内容提供器初始化成功,返回 false 则表示失败。注意,只有当存在
ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。
2. query()
从内容提供器中查询数据。使用 uri 参数来确定查询哪张表,projection 参数用于确
定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于
对结果进行排序,查询的结果存放在 Cursor 对象中返回。
3. insert()
向内容提供器中添加一条数据。使用 uri 参数来确定要添加到的表,待添加的数据
保存在 values 参数中。添加完成后,返回一个用于表示这条新记录的 URI。
4. update()
更新内容提供器中已有的数据。使用 uri 参数来确定更新哪一张表中的数据,新数
据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行,受影响的
行数将作为返回值返回。
5. delete()
从内容提供器中删除数据。使用 uri 参数来确定删除哪一张表中的数据,selection
和 selectionArgs 参数用于约束删除哪些行,被删除的行数将作为返回值返回。
6. getType()
根据传入的内容 URI 来返回相应的 MIME 类型。
可以看到,几乎每一个方法都会带有 Uri 这个参数,这个参数也正是调用 ContentResolver的增删改查方法时传递过来的。
也就是说我们自己创建的内容提供器,向外部提供的访问接口(增删改等接口)最终都是SQLite 数据库存储SQLiteDatabase增删改接口实现的,只是两者之间多了一个转换参数 Uri 。 Uri 参数正是保证隐私数据不被暴露的关键所在。因为所有的 CRUD 操作都一定要匹配到相应的内容 URI 格式才能进行的,而我们当然不可能向 UriMatcher 中添加隐私数据的 URI,所以这部分数据根本无法被外部程序访问到,安全问题也就不存在了。
使用内容提供器添加 Uri newUri = getContentResolver().insert(uri, values);
使用数据库添加
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.insert("Book", null, values)
如何才能保证隐私数据不会泄漏出去呢?其实多亏了内容提供器的良好机制,这个问题在不知不觉中已经被解决了。因为所有的 CRUD 操作都一定要匹配到相应的内容 URI 格式才能进行的,而我们当然不可能向 UriMatcher 中添加隐私数据的 URI,所以这部分数据根本无法被外部程序访问到,安全问题也就不存在了。