7.2 MediaProvider的启动及创建
第一、二、三条分析路线都将以下面这段示例为参考。
[—>MediaProvider客户端示例]
void QueryImage(Context context){
//①得到ContentResolver对象
ContentResolver cr=context.getContentResover();
Uri uri=MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
//②查询数据库
Cursor cursor=MediaStore.Images.Media.query(cr, uri, null);
cursor.moveToFirst();//③移动游标到头部
……//从游标中取出数据集
cursor.close();//④关闭游标
}
先介绍一下这段示例的情况:客户端(即运行本示例的进程)查询(query)的目标ContentProvider是MediaProvider,它运行于进程android.process.media中。假设目标进程此时还未启动。
本节的关注点集中在:
MediaProvider所在进程是如何创建的?MediaProvider又是如何创建的?
客户端通过什么和位于目标进程中的MediaProvider交互的?
先来看第一个关键函数getContentResolver。
7.2.1 Context的getContentResolver函数分析
根据第6章对Context的介绍,Context的getContentResolver最终会调用它所代理的ContextImpl对象的getContentResolver函数,此处直接看ContextImpl的代码。
[—>ContextImpl.java:getContentResolver]
public ContentResolver getContentResolver(){
return mContentResolver;
}
该函数直接返回mContentResolver,此变量在ContextImpl初始化时创建,相关代码如下:
[—>ContextImpl.java:init]
final void init(LoadedApk packageInfo, IBinder activityToken,
ActivityThread mainThread, Resources container, String basePackageName){
……
mMainThread=mainThread;//mainThread指向ActivityThread对象
//mContentResolver的真实类型是ApplicationContentResolver
mContentResolver=new ApplicationContentResolver(this, mainThread);
……
}
由以上代码可知,mContentResolver的真实类型是ApplicationContentResolver,它是ContextImpl定义的内部类并继承了ContentResolver。
getContentResolver函数比较简单,就分析到此。下面来看第二个关键函数。
提示 为了书写方便,后面将ContentProvider简称为CP,将ContentResolver简称为CR。