ContentProvider 的 query 流程分析
ContentProvider 将底层的数据结构(比如数据库、文件)封装并且提供增删改查的接口,提供给本应用或者外部的应用调用。
ContentResolver 的 query 方法
ContentProvider 的 query 操作是通过 ContentResolver 的 query 调用的,而不是直接调用 ContentProvider 的 query 方法,ContentProvider 的 query 方法类似于回调方法。
ContentResolver 的 query 方法一般调用方式如下:
context.getContentResolver().query(getUri(), null, null, null, null);
Context 是一个抽象类,它的具体实现都在 ContextImpl 类中。
ContextImpl 的 getContentResolver 方法如下:
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
}
mContentResolver 是 ContextImpl 构造时创建的。
构造如下:
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader) {
...
mContentResolver = new ApplicationContentResolver(this, mainThread);
}
可以看出传入了 ContextImpl 自身和 mainThread(ActivityThread),构造出 ApplicationContentResolver。
ApplicationContentResolver 继承了 ContentResolver(ContentResolver是一个抽象类)。它的实现如下:
private static final class ApplicationContentResolver extends ContentResolver {
...
@Override
protected IContentProvider acquireProvider(Context context, String auth) {
return mMainThread.acquireProvider(context,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), true);
}
}
可以看出它的 acquireProvider 方法直接调用了 ActivityThread 的 acquireProvider 方法,并返回一个 IContentProvider 对象。
ApplicationContentResolver 的 query 方法实际是它的父类 ContentResolver 的 query 方法。
ContentResolver 的 query 方法如下:
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable CancellationSignal cancellationSignal) {
...
IContentProvider unstableProvider = acquireUnstableProvider(uri);
...
try {
...
try {
qCursor = unstableProvider.query(mPackageName, uri, projection,
queryArgs, remoteCancellationSignal);
} catch (DeadObjectException e) {
// The remote process has died... but we only hold an unstable
// reference though, so we might recover!!! Let's try!!!!
// This is exciting!!1!!1!!!!1
unstableProviderDied(unstableProvider);
stableProvider = acquireProvider(uri);
...
qCursor = stableProvider.query(
mPackageName, uri, projection, queryArgs, remoteCancellationSignal

最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



