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