ContentProvider
ContentProvider(内容提供者)一般为存储和获取数据提供统一的接口,可以在不同的应用程序之间共享数据。
ContentProvider用于提供数据的统一访问格式,封装底层的具体实现。对于数据的使用者来说,无需知晓数据的来源是数据库、文件,或者网络,只需简单地使用ContentProvider提供的数据操作接口,也就是增(insert)、删(delete)、改(update)、查(query)四个过程。作为Android四大组件之一,并没有Activity那样复杂的生命周期,只有简单地onCreate过程。ContentProvider是一个抽象类,当实现自己的ContentProvider类,只需继承于ContentProvider,并且实现以下六个abstract方法即可:
- insert(Uri, ContentValues):插入新数据;
- delete(Uri, String, String[]):删除已有数据;
- update(Uri, ContentValues, String, String[]):更新数据;
- query(Uri, String[], String, String[], String):查询数据;
- onCreate():执行初始化工作;
- getType(Uri):获取数据MIME类型。
我们知道了ContentProvider是对数据层的封装后,那么大家可能会问我们要如何对ContentProvider进行增,删,改,查的操作呢?下面我们来介绍一个新的类ContentResolver,我们可以通过它,来对不同的ContentProvider进行操作。
ContentResolver
有些人可能会疑惑,为什么我们不直接访问Provider,而是又在上面加了一层ContentResolver来进行对其的操作,这样岂不是更复杂了吗?其实不然,大家要知道一台手机中可不是只有一个Provider内容,它可能安装了很多含有Provider的应用,比如联系人应用,日历应用,字典应用等等。有如此多的Provider,如果你开发一款应用要使用其中多个,如果让你去了解每个ContentProvider的不同实现,岂不是要头都大了。所以Android为我们提供了ContentResolver来统一管理与不同ContentProvider间的操作。
其他app或者进程想要操作ContentProvider,则需要先获取其相应的ContentResolver,再利用ContentResolver类来完成对数据的增删改查操作,下面列举一个查询操作,查询得到的是一个Cursor结果集,再通过操作该Cursor便可获取想要查询的结果。
ContentResolver cr = getContentResolver(); //获取ContentResolver
Uri uri = Uri.parse("content://com.xxx.MyApp/table/999");
Cursor cursor = cr.query(uri, null, null, null, null); //执行查询操作
...
cursor.close(); //关闭
那ContentResolver是如何来区别不同的ContentProvider的呢?这就涉及到URI(Uniform Resource Identifier)问题
ContentProvider中的URI
ContentProvider中的URI有固定格式,如下图:
- Authority:授权信息,用以区别不同的ContentProvider;
- Path:表名,用以区分ContentProvider中不同的数据表;
- Id:Id号,用以区别表中的不同数据。
参考资料:
ContentProviders官方向导:https://developer.android.google.cn/guide/topics/providers/content-providers
ContentProvider官方文档:https://developer.android.com/reference/android/content/ContentProvider.html
从源码的角度理解ContentProvider原理:http://gityuan.com/2016/07/30/content-provider/