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。