ContentProvider
为什么要有ContentProvider?
之前的存储都是放在具体应用程序下面(具体的私有路径,限制访问权限),如果能够共享?
系统由于安全的因素,提供一些数据访问,不能直接开放给开发者,如何让开发者能够访问到这些数据?
如果我写好的数据库程序,希望封装并且提供一套公共标准,让外部调用而不直接操作我的数据库,如果实现?
ContentProvider是什么?
ContentProvider是一套存储访问数据的通道,让你无需了解下面的存储细节实现数据操作及共享
无论具体存储是如何的,存在哪儿的,但对外提供的模型是统一的
定义了ContentProvider对象,会在系统初始化的时候自动实例化(监听),无需我们手动去实例化对象
我们只需要通过ContentResolver去取和操作数据即可
ContentResolver与ContentProvider配对
特性:
ContentProvider是唯一的共享程序间数据方式,Android没有提供公共数据去让不同的程序去共享访问
其实ContentResolver与ContentProvider就像是C/S架构
首先要有网址,其次客户端发起请求,最后服务器端回复
需要再AndroidManifest.xml中配置ContentProvider
<provider android:authorities="com.example.transportationprovider" android:name=".provider.MyContentProvider" />
定义服务器端
public class MyContentProvider extends ContentProvider{
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri uri, String[] strings, String s, String[] strings2, String s2) {
if (uri.getAuthority().contains("com.example.transportationprovider"))
{
Log.i("log", "provider query");
}
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
if (uri.getAuthority().contains("com.example.transportationprovider"))
{
Log.i("log", "provider insert");
}
return null;
}
@Override
public int delete(Uri uri, String s, String[] strings) {
return 0;
}
@Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
return 0;
}
}
这些方法都是继承ContentProvider必须实现的
调用时
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ContentResolver _Resolver = getContentResolver();
Cursor _Cursor = _Resolver.query(Uri.parse("content://com.example.transportationprovider"), null, null, null, null);
}
});
这就相当于客户端发起的请求
以上就是一个很简单的ContentProvider相关的实现(里面啥都木有好伐……)
可以在自定义的ContentProvider中调用SQLiteDatabase进行相关的增删改查操作
一些系统提供的ContentProvider
·Browser:浏览器的书签,历史记录等
·CallLog:呼叫记录,包括呼入呼出
·ContactsContact:通讯录相关信息
·Calendar:日历相关信息
·MediaStore:媒体存储
·Settings:系统设置信息的部分内容
·UserDictionary:用户词典内容
调用通讯录的例子:
通过调用query,相当于是链接到了服务器端(的数据库)
startManagingCursor接收查询到结果的Cursor,对其进行管理和监视
当Activity消亡不再使用时就会销毁Cursor的链接,使其不再保持链接(重要)
如果发现别的进程无法调用提供的ContentProvider,那可能是因为没有对外提供
将定义的provider中加入android:multiprocess="true"就能在不同进程间访问了
总结:
1、定义Provider
(1)写一个类继承ContentProvider
(2)实现ContentProvider的方法
(3)注册到manifest中,进程间提供加入multiprocess属性
2、使用ContentResolver调用ContentProvider中的内容(代理模式,使用Binder)
ContentProvider的机制
当程序安装/卸载时,Provider将会注册/删除到ProviderManager中,相当于有一个链表,
使用ContentResolver访问时,会到ProviderManager中寻找,并启动相关Provider
所以Provider不是由主Activity启动的
ContentProvider调用的时候宿主进程生命周期
接收调用的时候启动宿主进程,操作完毕后,宿主进程为empty