内容提供者与 SQlite 使用注意点笔记

ContentProvider 是 Android 四大组件之一,方便我们跨应用(跨应用本身就是跨进程)、跨进程访问与操作数据,之前学过但是早就忘了,故温习一遍,而 SQlite 是 Android 提供的轻量级数据库,自定义 ContentProvider 时也自己提供了数据,所以捎带手回顾了一下 SQlite。

1我们通过 ContentResolver 访问数据,比如增删改查,而这些操作其实是 ContentResolver 底层去调用 ContentProvider 的对应的操作。

2.通过调用 getContentResolver() 去获取 ContentResolver,然后进行操作。

3.做好把对 ContentResolver 的操作再放后台线程,查询时其实还可以使用 CursorLoader 自动异步进行。

4.读写数据前注意权限问题。

5.要防止 SQL 注入。

6.通过继承 ContentProvider 来实现自己的 ContentProvider,并实现onCreate()、query()、update()、insert()、delete()、getType(),除了 onCreate() 运行在主线程,所以不要在 onCreate() 做耗时操作,其他五个方法都运行在都运行在 Binder 线程。

内容提供者与 SQlite 使用注意点笔记_第1张图片
运行截图.png

7.ContentProvider 的 query() 方法只有在出错是才返回 null,否则就算没有数据也会返回一个长度为 0 的 Cursor。

8.ContentProvider 的 insert() 方法一般在成功后返回带有 Id 的 URI,而插入失败返回 null。

9.update()、delete() 返回成功操作的条数。

10.自己在定义 ContentProvider 后,需要在清单文件中声明,声明是一定要声明 android:authorities,这时 ContentProvider 的唯一标识,也是别人访问你的 ContentProvider 使用的值。

11.如果想要声明 ContentProvider 的使用权限要在自己的清单文件中自定义好权限,然后提供给别人使用。对方使用的使用就直接声明好对应权限即可,而自定义权限中的 android:protectionLevel 表示权限级别,这里是普通权限。

别的 App 需要声明

内容提供者与 SQlite 使用注意点笔记_第2张图片
声明权限.png

12.别的 App 中想要使用自己自定义 ContentProvider 还有一点需要注意要在 下声明 android:exported="true",这样其他 App 才能正常访问这个ContentProvider。

13.侦听 ContentProvider 数据变化可以使用自定义的 ContentObserver 实现 onChange() 即可,然后在 ContentResolver 中注册侦听器即可,注册时第二参数需要传递一个 boolean 值,该值表示是否可以侦听到子级数据的变化,记得反注册哟。

14.ContentResolver 的 applyBatch() 可以同时向多个表中插入数据,而 insert() 以及 bulkInsert() 只是针对单一 URI 插入,只是 bulkInsert() 向一个表中同时插入多条。

15.SQLiteDatabase 是用于展示管理 SQLite 数据库中的方法,因为 SQLite 本身是用 C 写的,SQLiteDatabase 是 SQLite 在 Java 层分一层封装。

16.SQLiteOpenHelper 是我们对 SQLiteDatabase 进行管理操作的类,SQLiteOpenHelper 本身是抽象类,而我们需要实现自己的 SQLiteOpenHelper,在里面创建或者升级数据库,而我们通过getWritable/ReadaleDatabase() 获取对应的 SQLiteDatabase。

17.我们无需手动调用 SQLiteOpenHelper 的 onCreate(),getWritable/ReadaleDatabase() 会隐式帮我调用 onCreate()。

18.使用 SQLiteDatabase 插入数据时,我们可以使用insert() 或者 insertWithOnConflict(),后者多了一个冲突解决器,例如下面这行代码,冲突解决器为 CONFLICT_REPLACE,这个解决器的效果是如果数据不存在时插入,如果存在则更新数据,与 SQLiteDatabase 的 replace() 效果相同,因为源码中就是调用 insertWithOnConflict(xxx, xxx, xxx, SQLiteDatabase.CONFLICT_REPLACE)。

db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
内容提供者与 SQlite 使用注意点笔记_第3张图片
SQLiteDatabase 中的 replace() 方法

19.升级数据库时记得不仅要在 onUpgrade() 中写对应的 SQL 执行语句,还需要在 onCreate() 中写入新的字段,因为有些用户是从新版本开始安装的 App。

20.并发访问时,多个线程中同时使用同一个 SQLiteOpenHelper 实例其实是顺序访问,问并发访问需要创建多个 SQLiteOpenHelper 实例。

21.还有一点需要注意,当我们查询时候,应该小心调用 cursor.moveToFirst() 因为正常情况下,最好不要不同调用 cursor.moveToNext() 这样会导致光标连续移动,从而错过第一个位置的数据,所以 cursor.moveToFirst() 配合 do...while 更合适,单纯 cursor.moveToNext() 更适合 while。

这些只是个人学习与使用中一些知识点总结,如需 Demo 请留言。

你可能感兴趣的:(内容提供者与 SQlite 使用注意点笔记)