基于N源码的ContentProvider调用流程分析

内容提供者顾名思义是用来提供数据的,现在假设我要获取系统联系人的数据,可以这样查询:

getContentResolver().query(Contacts.CONTENT_URI, null, null, null, null);

这样就会跳转到联系人的provider的query:

public class ContactsProvider2 extends AbstractContactsProvider
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder, CancellationSignal cancellationSignal) {
  

这个过程是如何做到的?下面来跟下这个流程:

调用getContentResolver会进入ContextImpl.java:

    public ContentResolver getContentResolver() {
        return mContentResolver;
    }

mContentResolver是ApplicationContentResolver类型,在实例化ContextImpl的时候初始化。

接着进入ContentResolver.java中的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) {
        Preconditions.checkNotNull(uri, "uri");
        IContentProvider unstableProvider = acquireUnstableProvider(uri);
        if (unstableProvider == null) {
            return null;
        }
        qCursor = unstableProvider.query(mPackageName, uri, projection,
                        selection, selectionArgs, sortOrder, remoteCancellationSignal);
	}

先调用acquireUnstableProvider来获取IContentProvider binder接口,这个接口的真正的实现者其实是ContentProvider中的Transport:

class Transport extends ContentProviderNative {
  
abstract public class ContentProviderNative extends Binder implements IContentProvider {
  

可以看到ContentProviderNative继承Binder实现IContentProvider接口,就是服务的中间者stub的替身,真正的实现者在它的子类当中:

    class Transport extends ContentProviderNative {
        AppOpsManager mAppOpsManager = null;
        int mReadOp = AppOpsManager.OP_NONE;
        int mWriteOp = AppOpsManager.OP_NONE;

        @Override
        public Cursor query(String callingPkg, Uri uri, String[] projection,
                String selection, String[] selectionArgs, String sortOrder,
                ICancellationSignal cancellationSignal) {
                Cursor cursor = ContentProvider.this.query(uri, projection, selection,
                        selectionArgs, sortOrder, CancellationSignal.fromTransport(
                                cancellationSignal));
		}

这里调用ContentProvider.this.query其实就是调用ContentProvider子类的query,比如这里调用的是联系人的ContactsProvider2,它继承AbstractContactsProvider,AbstractContactsProvider继承ContentProvider。

知道了这个binder的真身后,我们回到前面ContentResolver中的query中,是通过acquireUnstableProvider来获取binder接口,跟踪到ApplicationContentResolver中的acquireUnstableProvider:

        protected IContentProvider acquireUnstableProvider(Context c, String auth) {
            return mMainThread.acquireProvider(c,
                    ContentProvider.getAuthorityWithoutUserId(auth),
                    resolveUserIdFromAuthority(auth), false);
        }

接着进入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;
        }

        // There is a possible race here.  Another thread may try to acquire
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值