ContentProvider 的 query 流程分析

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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值