一,写在前面
在文章
Android 如何自定义一个ContentProvider中,介绍了如何使用以及自定义一个ContentProvider,本篇不再介绍如何使用ContentProvider访问其他应用的数据。在阅读本篇文章前,建议先了解Activity的启动流程,可参考文章
Android Activity的启动流程源码解析(8.0) ,将不再对重复的代码细节进行分析。
二,启动ContentProvider的入口
如何启动一个ContentProvider呢?在一个Activity类中,可以调用getContentResolver().query(...)查询指定uri对应的数据,在这个过程中若ContentProvider没有启动,则会启动ContentProvider。当然,相应的insert,delete,update方法也可以启动ContentProvider,本篇文章以query方法为例进行分析。
获取ContentResolver的对象,实际上调用的是ContextWrapper$getContentResolver方法,ContextWrapper是抽象类Context的一个子类。
查看ContextWrapper$getContentResolver方法源码:
@Override
public ContentResolver getContentResolver() {
return mBase.getContentResolver();
}
第3行,变量mBase对应的是ContextImpl对象,分析见
Android Activity的启动流程源码解析(8.0) ,这里不再重复阐述。
查看ContextImpl$getContentResolver方法源码:
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
}
第3行,变量mContentResolver的初始化在ContextImpl的构造函数中完成,mContentResolver = new ApplicationContentResolver(this, mainThread, user),也就是返回的是ApplicationContentResolver的实例。值得一提的是,ContextImpl对象的创建是在启动Activity的流程中完成,具体分析见
Android Activity的启动流程源码解析(8.0) ,这里不再重复阐述。
ApplicationContentResolver是ContextImpl的一个内部类,且继承类ContentResolver。调用getContentResolver().query(...)方法,是从父类ContentResolver继承的query方法。
查看ContentResolver$query方法源码:
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder,
@Nullable CancellationSignal cancellationSignal) {
//...
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
return null;
}
//...
qCursor = unstableProvider.query(mPackageName, uri, projection,
selection, selectionArgs, sortOrder, remoteCancellationSignal);
//...
}
第8行,获取一个IContentProvider类型的对象unstableProvider。
启动ContentProvider从这里开始分析,后面会详细分析。
第9行,对变量unstableProvider进行判空检查;
第15行,根据指定uri,执行查询数据操作,
文章的最后会详细分析。
查看ContentResolver$acquireUnstableProvider方法(一个参数)源码:
public final IContentProvider acquireUnstableProvider(Uri uri) {
if (!SCHEME_CONTENT.equals(uri.getScheme())) {
return null;
}
String auth = uri.getAuthority();
if (auth != null) {
return acquireUnstableProvider(mContext, uri.getAuthority());
}
return null;
}
第2行,对uri的scheme进行检查;
第7行,逻辑跳到ApplicationContentResolver$acquireUnstableProvider方法(两个参数);
查看ApplicationContentResolver$acquireUnstableProvider方法源码:
@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return mMainThread.acquireProvider(c,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), false);
}
第3行,变量mMainThread是一个ActivityThread类型的对象,该变量的初始化也是在ContextImpl的构造函数中完成。
查看ActivityThread$acquireProvider方法源码:
public final IContentProvider acquireProvider(
Context c, String auth, int userId, boolean stable) {
final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
if (provider != null) {
return provider;
}
ContentProviderHolder holder = null;
//...
holder = ActivityManager.getService().getContentProvider(
getApplicationThread(), auth, userId, stable);
//...
holde