content provider 介绍
content provider 是Android四大组件之一,其功能是在不同程序之间实现数据共享。在Android系统中,应用程序之间是相互独立的,分别运行在自己的进程中。若应用程序之间需要共享数据,就需要用到content provider 。它不仅允许一个程序访问另一个程序中的数据,同时还可以选择只对那一部分数据进行共享,从而保证程序中的营私数据不被泄露。
contentProvider是不同应用程序之间进行数据共享的标准api,如果想要访问content provider中共享的数据,需要借助contentResolver类来进行数据共享。contentReslover类通过uri的形式对数据进行增/删/改/查的操作。
uri为内容提供者中的数据建立了唯一标识符,它主要有scheme、authorities、path三部分组成,如下图所示
- scheme:以 “content://”开头的前缀,表明这个数据被contentProvider控制,不会被修改,由Android规定。
- authority:为创建的内容提供者指定属性值,主要用来区分不同的应用程序,一般为了避免冲突,都会采用程序包名的方式命名
- path:代表资源(或者数据),当访问者需要操作不同的数据时,这个部分可以动态修改。
ContentProvider的使用
1.创建contentProvider类
通过创建自定义ContentProvider类(该类继承ContentProvider抽象类),通过该类去实现对数据的增删改查。相关方法如下:
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
2.注册contentProvider
在androidManifest.xml文件中注册contentprovider,示例如下:
<provider
android:name=".MyContentProvider"
android:authorities="com.xiaoyao.test"
android:enabled="true"
android:exported="true"></provider>
3.通过contentReslover查询数据
通过context.getContentResolver()方法获得contentResolver对象,然后调用contentResolver的insert()、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)
ContentObserver
工作原理
contentObserver为Android系统提供的内容观察者,主要用来监听contentProvider中共享的数据是否发生变化并及时通知外界。常见有:监听短信、监听多媒体库等
contentObserver时通过URI来观察指定数据的,其工作原理图如下:
使用
创建contentObserver类
这个类主要实现两个方法,方法代码如下:
class MycontentObserver extends ContentObserver{
//可以是主线程中的Handler,也可以是任意handler
public MycontentObserver(Handler handler) {
super(handler);
}
//当观察到的Uri代表的数据发生变化时,会触发该方法,需要更新UI时,会在此方法内通过Handler传递
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
}
}
- 在contentProvider中调用notifyChange()方法
由于ContentProvider是通过delete()、insert()、update()这个几个方法让数据发生变化的,所以在在这个几个方法后面添加代码通知数据变化。
getContentResolver().notifyChange((Uri uri, ContentObserver observer);
- 注册ContentObserver
在activity内注册内容观察者,有需要更新UI时,会在handler内进行更新。注册内容观察者相关代码如下:
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://aaa.bbb.ccc");
resolver.registerContentObserver(uri,true,new MycontentObserver(new Handler()));