Android-33源码分析: ContentProvider插入查询注册流程

Android-33源码分析: ContentProvider插入查询注册流程_第1张图片

注意点:
1:Activity中使用getContentResolver()获取ContentResolver,
其实就是Context实现类ContextImpl中getContentResolver()所返回该类中的静态内不类ApplicationContentResolver
ApplicationContentResolver继承ContentResolver拥有它的能力

2:IContentProvider AIDL的实现类为抽象类ContentProviderNative
ContentProvider的内部类 Transport继承ContentProviderNative

3:ContentResolver中的getContentService()获取的IContentService
IContentService AIDL的实现类为ContentService

4:ContentService中ObserverCollector 就是收集外部注册到该服务中的观察者,方便同意分发或通知内容变化

5:IContentObserver AIDL的实现类为 ContentObserver中的Transport
ContextImpl中
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
    return mMainThread.acquireProvider(c,
            ContentProvider.getAuthorityWithoutUserId(auth),
            resolveUserIdFromAuthority(auth), false);
}
ActivityThread中
public final IContentProvider acquireProvider(
        Context c, String auth, int userId, boolean stable) {
/**
 * 判断是否ContentProvider是否初始化
 * 如果没有初始化初始化installProvider方法
 * 
 * 注意:
 * 应用自己内部的ContentProvider会在ActivityThread的main方法会去初始化
 * 如果是调用外部的ContentProvider可能卫初始化
 *
    final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
    if (provider != null) {
        return provider;
    }
    // Install provider will increment the reference count for us, and break
    // any ties in the race.
    holder = installProvider(c, holder, holder.info,
            true /*noisy*/, holder.noReleaseNeeded, stable);
    return holder.provider;
}
== insert源码流程========================================================================================
Activity
开启插入
getContentResolver().insert(TestContentProvider.URI_USER, contentValues);
ContentResolver

public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url,
            @Nullable ContentValues values, @Nullable Bundle extras) {
        Objects.requireNonNull(url, "url");

        try {
            if (mWrapped != null) return mWrapped.insert(url, values, extras);
        } catch (RemoteException e) {
            return null;
        }

        /**
         * 获取IContentProvider的实现Transpor
         * Transpor在ContentProvider中且继承ContentProviderNative
         * ContentProviderNative 继承 Binder 实现 IContentProvider
         */
        IContentProvider provider = acquireProvider(url);
        if (provider == null) {
            throw new IllegalArgumentException("Unknown URL " + url);
        }
        try {
            long startTime = SystemClock.uptimeMillis();
            /**
             * 执行ContentProvider中实现类Transpor的insert方法
             */
            Uri createdRow = provider.insert(mContext.getAttributionSource(), url, values, extras);
            long durationMillis = SystemClock.uptimeMillis() - startTime;
            maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
            return createdRow;
        } catch (RemoteException e) {
            // Arbitrary and not worth documenting, as Activity
            // Manager will kill this process shortly anyway.
            return null;
        } finally {
            releaseProvider(provider);
        }
    }
ContentProvider

  public Uri insert(@NonNull AttributionSource attributionSource, Uri uri,
                ContentValues initialValues, Bundle extras) {
            uri = validateIncomingUri(uri);
            int userId = getUserIdFromUri(uri);
            uri = maybeGetUriWithoutUserId(uri);
            if (enforceWritePermission(attributionSource, uri)
                    != PermissionChecker.PERMISSION_GRANTED) {
                final AttributionSource original = setCallingAttributionSource(
                        attributionSource);
                try {
                    return rejectInsert(uri, initialValues);
                } finally {
                    setCallingAttributionSource(original);
                }
            }
            traceBegin(TRACE_TAG_DATABASE, "insert: ", uri.getAuthority());
            final AttributionSource original = setCallingAttributionSource(
                    attributionSource);
            try {
                /**
                 * 执行的是ContentProvider实现的接口ContentInterface中insert方法
                 * 最后执行ContentProvider中抽象方法insert
                 */
                return maybeAddUserId(mInterface.insert(uri, initialValues, extras), userId);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
                setCallingAttributionSource(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
            }
        }
== query源码流程 ========================================================================================
Activity

getContentResolver().query(TestContentProvider.URI_USER...);
ContentResolver

    public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
            @Nullable String[] projection, @Nullable Bundle queryArgs,
            @Nullable CancellationSignal cancellationSignal) {
        Objects.requireNonNull(uri, "uri");

        try {
            if (mWrapped != null) {
                return mWrapped.query(uri, projection, queryArgs, cancellationSignal);
            }
        } catch (RemoteException e) {
            return null;
        }

        /**
         * 获取IContentProvider的实现Transpor
         * Transpor在ContentProvider中且继承ContentProviderNative
         * ContentProviderNative 继承 Binder 实现 IContentProvider
         */
        IContentProvider unstableProvider = acquireUnstableProvider(uri);
        if (unstableProvider == null) {
            return null;
        }
        IContentProvider stableProvider = null;
        Cursor qCursor = null;
        try {
            long startTime = SystemClock.uptimeMillis();

            ICancellationSignal remoteCancellationSignal = null;
            if (cancellationSignal != null) {
                cancellationSignal.throwIfCanceled();
                remoteCancellationSignal = unstableProvider.createCancellationSignal();
                cancellationSignal.setRemote(remoteCancellationSignal);
            }
            try {
                /**
                 * 执行ContentProvider中实现类Transpor的insert方法
                 */
                qCursor = unstableProvider.query(mContext.getAttributionSource(), 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);
                if (stableProvider == null) {
                    return null;
                }
                qCursor = stableProvider.query(mContext.getAttributionSource(), uri, projection,
                        queryArgs, remoteCancellationSignal);
            }
            if (qCursor == null) {
                return null;
            }

            // Force query execution.  Might fail and throw a runtime exception here.
            qCursor.getCount();
            long durationMillis = SystemClock.uptimeMillis() - startTime;
            maybeLogQueryToEventLog(durationMillis, uri, projection, queryArgs);

            // Wrap the cursor object into CursorWrapperInner object.
            final IContentProvider provider = (stableProvider != null) ? stableProvider
                    : acquireProvider(uri);
            final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
            stableProvider = null;
            qCursor = null;
            return wrapper;
        } catch (RemoteException e) {
            // Arbitrary and not worth documenting, as Activity
            // Manager will kill this process shortly anyway.
            return null;
        } finally {
            if (qCursor != null) {
                qCursor.close();
            }
            if (cancellationSignal != null) {
                cancellationSignal.setRemote(null);
            }
            if (unstableProvider != null) {
                releaseUnstableProvider(unstableProvider);
            }
            if (stableProvider != null) {
                releaseProvider(stableProvider);
            }
        }
    }
ContentProvider

        @Override
        public Cursor query(@NonNull AttributionSource attributionSource, Uri uri,
                @Nullable String[] projection, @Nullable Bundle queryArgs,
                @Nullable ICancellationSignal cancellationSignal) {
            uri = validateIncomingUri(uri);
            uri = maybeGetUriWithoutUserId(uri);
            if (enforceReadPermission(attributionSource, uri)
                    != PermissionChecker.PERMISSION_GRANTED) {
                 Cursor cursor;
                final AttributionSource original = setCallingAttributionSource(
                        attributionSource);
                try {
                    /**
                     * 执行的是ContentProvider实现的接口ContentInterface中query方法
                     * 最后执行ContentProvider中抽象方法query
                     */
                    cursor = mInterface.query(
                            uri, projection, queryArgs,
                            CancellationSignal.fromTransport(cancellationSignal));
                } catch (RemoteException e) {
                    throw e.rethrowAsRuntimeException();
                } finally {
                    setCallingAttributionSource(original);
                }
                if (cursor == null) {
                    return null;
                }

                // Return an empty cursor for all columns.
                return new MatrixCursor(cursor.getColumnNames(), 0);
            }
            traceBegin(TRACE_TAG_DATABASE, "query: ", uri.getAuthority());
            final AttributionSource original = setCallingAttributionSource(
                    attributionSource);
            try {
                return mInterface.query(
                        uri, projection, queryArgs,
                        CancellationSignal.fromTransport(cancellationSignal));
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            } finally {
                setCallingAttributionSource(original);
                Trace.traceEnd(TRACE_TAG_DATABASE);
            }
        }

== registerContentObserver注册内容观察者以及通知内容变化分发 ===================================  

Activity

       // 注册的观察者不能为null     
       getContentResolver().registerContentObserver(TestContentProvider.URI_USER, false, new ContentObserver(new Handler()) {
                @Override
                public void onChange(boolean selfChange) {
                    Log.i(TAG, "onChange");
                    super.onChange(selfChange);
                }
            });
ContentResolver

public final void registerContentObserver(Uri uri, boolean notifyForDescendents,
            ContentObserver observer, @UserIdInt int userHandle) {
        try {
            /**
             * 把当前ContentObserver中AIDL接口IContentObserver的实现类Transport注册到该服务中
             * (Transport继承IContentObserver.Stub)
             * 方便后期ContentService通过该接口实现发送通知消息
             */
            getContentService().registerContentObserver(uri, notifyForDescendents,
                    observer.getContentObserver(), userHandle, mTargetSdkVersion);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

public static IContentService getContentService() {
        if (sContentService != null) {
            return sContentService;
        }
        /**
         * 获取IContentService的实现类ContentService
         */
        IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
        sContentService = IContentService.Stub.asInterface(b);
        return sContentService;
    }
ContentService

public void registerContentObserver(Uri uri, boolean notifyForDescendants,
            IContentObserver observer, int userHandle, int targetSdkVersion) {
   
        /**
         * observer为刚才注册的ContentObserver.Transport
         * 添加到到该观察者的节点上
         * ArrayList mObservers = new ArrayList()
         * 中
         */
        synchronized (mRootNode) {
            mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
                    uid, pid, userHandle);
            if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
                    " with notifyForDescendants " + notifyForDescendants);
        }
    }

== notifyChange通知内容变化分发 ===================================  

TestContentProvider是你自己继承的ContentProvider类

       /**
         * 数据有 增删该查 都可以通过该方法通知已经注册的观察者
         */
        getContext().getContentResolver().notifyChange(TestContentProvider.URI_USER, null);

ContentResolver

    public void notifyChange(@NonNull Uri[] uris, ContentObserver observer, @NotifyFlags int flags,
            @UserIdInt int userHandle) {
        try {
            /**
             *获取到ContentService执行notifyChange
             */
            getContentService().notifyChange(
                    uris, observer == null ? null : observer.getContentObserver(),
                    observer != null && observer.deliverSelfNotifications(), flags,
                    userHandle, mTargetSdkVersion, mContext.getPackageName());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public static IContentService getContentService() {
        if (sContentService != null) {
            return sContentService;
        }
        /**
         * 获取IContentService的实现类ContentService
         */
        IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
        sContentService = IContentService.Stub.asInterface(b);
        return sContentService;
    }
ContentService

    public void notifyChange(Uri[] uris, IContentObserver observer,
            boolean observerWantsSelfNotifications, int flags, int userId,
            int targetSdkVersion, String callingPackage) {
        if (DEBUG) {
            Slog.d(TAG, "Notifying update of " + Arrays.toString(uris) + " for user " + userId
                    + ", observer " + observer + ", flags " + Integer.toHexString(flags));
        }

        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        final int callingUserId = UserHandle.getCallingUserId();

        /**
         * 先初始化一个观察者收集器 方便存放观察者
         */
        // Set of notification events that we need to dispatch
        final ObserverCollector collector = new ObserverCollector();

        // Set of content provider authorities that we've validated the caller
        // has access to, mapped to the package name hosting that provider
        final ArrayMap, String> validatedProviders = new ArrayMap<>();

        for (Uri uri : uris) {
            // Validate that calling app has access to this provider
            final int resolvedUserId = handleIncomingUser(uri, callingPid, callingUid,
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true, userId);
            final Pair provider = Pair.create(uri.getAuthority(), resolvedUserId);
            if (!validatedProviders.containsKey(provider)) {
                final String msg = LocalServices.getService(ActivityManagerInternal.class)
                        .checkContentProviderAccess(uri.getAuthority(), resolvedUserId);
                if (msg != null) {
                    if (targetSdkVersion >= Build.VERSION_CODES.O) {
                        throw new SecurityException(msg);
                    } else {
                        if (msg.startsWith("Failed to find provider")) {
                            // Sigh, we need to quietly let apps targeting older API
                            // levels notify on non-existent providers.
                        } else {
                            Log.w(TAG, "Ignoring notify for " + uri + " from "
                                    + callingUid + ": " + msg);
                            continue;
                        }
                    }
                }

                // Remember that we've validated this access
                final String packageName = getProviderPackageName(uri, resolvedUserId);
                validatedProviders.put(provider, packageName);
            }

            /**
             * 把ObserverNode节点保存的ContentObserver.Transport复制到观察者收集器中
             * 最后执行ObserverCollector的collect方法
             */
            // No concerns raised above, so caller has access; let's collect the
            // notifications that should be dispatched
            synchronized (mRootNode) {
                final int segmentCount = ObserverNode.countUriSegments(uri);
                mRootNode.collectObserversLocked(uri, segmentCount, 0, observer,
                        observerWantsSelfNotifications, flags, resolvedUserId, collector);
            }
        }

        final long token = clearCallingIdentity();
        try {
            /**
             * 开启数据变化的分发
             */
            // Actually dispatch all the notifications we collected
            collector.dispatch();

            for (int i = 0; i < validatedProviders.size(); i++) {
                final String authority = validatedProviders.keyAt(i).first;
                final int resolvedUserId = validatedProviders.keyAt(i).second;
                final String packageName = validatedProviders.valueAt(i);

                // Kick off sync adapters for any authorities we touched
                if ((flags & ContentResolver.NOTIFY_SYNC_TO_NETWORK) != 0) {
                    SyncManager syncManager = getSyncManager();
                    if (syncManager != null) {
                        syncManager.scheduleLocalSync(null /* all accounts */, callingUserId,
                                callingUid,
                                authority, getSyncExemptionForCaller(callingUid),
                                callingUid, callingPid, callingPackage);
                    }
                }

                // Invalidate caches for any authorities we touched
                synchronized (mCache) {
                    for (Uri uri : uris) {
                        if (Objects.equals(uri.getAuthority(), authority)) {
                            invalidateCacheLocked(resolvedUserId, packageName, uri);
                        }
                    }
                }
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

public void dispatch() {
            for (int i = 0; i < collected.size(); i++) {
                final Key key = collected.keyAt(i);
                final List value = collected.valueAt(i);

                final Runnable task = () -> {
                    try {
                        key.observer.onChangeEtc(key.selfChange,
                                value.toArray(new Uri[value.size()]), key.flags, key.userId);
                    } catch (RemoteException ignored) {
                    }
                };

                // Immediately dispatch notifications to foreground apps that
                // are important to the user; all other background observers are
                // delayed to avoid stampeding
                final boolean noDelay = (key.flags & ContentResolver.NOTIFY_NO_DELAY) != 0;
                final int procState = LocalServices.getService(ActivityManagerInternal.class)
                        .getUidProcessState(key.uid);
                if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND || noDelay) {
                    task.run();
                } else {
                    BackgroundThread.getHandler().postDelayed(task, BACKGROUND_OBSERVER_DELAY);
                }
            }
        }
ContentObserver

        public void onChangeEtc(boolean selfChange, Uri[] uris, int flags, int userId) {
            ContentObserver contentObserver = mContentObserver;
            if (contentObserver != null) {
                contentObserver.dispatchChange(selfChange, Arrays.asList(uris), flags, userId);
            }
        }

    public final void dispatchChange(boolean selfChange, @NonNull Collection uris,
            @NotifyFlags int flags, @UserIdInt int userId) {
        if (mHandler == null) {
            onChange(selfChange, uris, flags, userId);
        } else {
            mHandler.post(() -> {
                onChange(selfChange, uris, flags, userId);
            });
        }
    }

你可能感兴趣的:(android)