内容提供者(ContentProvider)主要用于在不同的应用程序之间实现数据共享的功
能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被
访数据的安全性。目前,使用内容提供者是 Android 实现跨程序共享数据的方式之一。
ContentProvider和ActivityManagerService通信的简单流程图如下:
ProcessRecord:记录当前运行的进程信息
ContentProviderConnection:封装ContentProviderRecord和ContentProvider客户端进程ProcessRecord信息
ContentProviderRecord: AMS中记录已经发布的ContentProvider信息
ActivityThread:对应APP进程中的主线程
ContentProvider和ActivityManagerService中的类图关系如下:
getContentResolver.query到ActivityManagerService的时序图如下:
ActivityManagerService启动ContentProvider的时序图如下:
分析getContentResolver.query具体流程如下,insert,delete等函数相似不做分析
getContentResolver().query(uri, projection, selection, null, sortOrder);
ContextWrapper.java (frameworks\base\core\java\android\content)
public ContentResolver getContentResolver() {
// mBase指向的是ContextImpl对象
return mBase.getContentResolver();
}
ContextImpl.java (frameworks\base\core\java\android\app)
public ContentResolver getContentResolver() {
// mContentResolver对象是在ContextImpl创建的,getContentResolver()返回的对象为ApplicationContentResolver
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) {
mOuterContext = this;
mMainThread = mainThread;
mActivityToken = activityToken;
mFlags = flags;
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
}
// ApplicationContentResolver为ContextImpl的内部类
private static final class ApplicationContentResolver extends ContentResolver {
private final ActivityThread mMainThread;
private final UserHandle mUser;
public ApplicationContentResolver(Context context, ActivityThread mainThread, UserHandle user) {
super(context);
mMainThread = Preconditions.checkNotNull(mainThread);
mUser = Preconditions.checkNotNull(user);
}
}
ContentResolver.java (frameworks\base\core\java\android\content)
ContentResolver.query函数分析
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable CancellationSignal cancellationSignal) {
Preconditions.checkNotNull(uri, "uri");
// 调用ApplicationContentResolver的acquireUnstableProvider函数
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
return null;
}
IContentProvider stableProvider = null;
Cursor qCursor = null;
try {
long startTime = SystemClock.uptimeMillis();
try {
//通过AMS获取到IContentProvider代理对象,调用代理对象的query函数, 最终会调用ContentProvider的query函数
qCursor = unstableProvider.query(mPackageName, uri, projection,queryArgs, remoteCancellationSignal);
} catch (DeadObjectException e) {
unstableProviderDied(unstableProvider);
stableProvider = acquireProvider(uri);
if (stableProvider == null) {
return null;
}
qCursor = stableProvider.query(
mPackageName, 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);
// Binder通信获取共享内存的fd, 将数据信息封装在Cursor中
final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
stableProvider = null;
qCursor = null;
// 将cursor对象返回给调用者
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);
}
}
}
调用ApplicationContentResolver的acquireUnstableProvider函数mMainThread为ActivityThread对象,接着调用ActivityThread的acquireUnstableProvider函数
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return mMainThread.acquireProvider(c,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), false);
}
ActivityThread.java (dframeworks\base\core\java\android\app)
ActivityThread.acquireProvider函数分析
public final IContentProvider acquireProvider(
Context c, String auth, int userId, boolean stable) {
// 1查看缓存中是否存在对应的IContentProvider代理对象,如果有直接返回
final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
if (provider != null) {
return provider;
}
ContentProviderHolder holder = null;
try {
// 2向AMS请求获取ContentProviderHolder对象
holder = ActivityManager.getService().getContentProvider(
getApplicationThread(), auth, userId, stable);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
if (holder == null) {
Slog.e(TAG, "Failed to find provider info for " + auth);
return null;
}
// 安装 provider
holder = installProvider(c, holder, holder.info,
true /*noisy*/, holder.noReleaseNeeded, stable);
return holder.provider;
}
ActivityThread.acquireExistingProvider函数分析
public final IContentProvider acquireExistingProvider(
Context c, String auth, int userId, boolean stable) {
synchronized (mProviderMap) {
// 从hashMap查看是否有ProviderClientRecord对象没有则返回
final ProviderKey key = new ProviderKey(auth, userId);
final ProviderClientRecord pr = mProviderMap.get(key);
if (pr == null) {
return null;
}
// 之前获取过,则从mProviderMap中获取
IContentProvider provider = pr.mProvider;
IBinder jBinder = provider.asBinder();
if (!jBinder.isBinderAlive()) {
// The hosting process of the provider has died; we can't
// use this one.
Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
+ ": existing object's process dead");
handleUnstableProviderDiedLocked(jBinder, true);
return null;
}
// Only increment the ref count if we have one. If we don't then the
// provider is not reference counted and never needs to be released.
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
// 增加对应的内容提供者的引用计数
incProviderRefLocked(prc, stable);
}
// 返回对应的IContentProvider
return provider;
}
}
ActivityManagerService.java (frameworks\base\services\core\java\com\android\server\am)
ActivityManager.getService()即为ActivityManagerService的代理对象,最终调用的是ActivityManagerService的getContentProvider函数
ActivityManagerService.getContentProvider函数分析
public final ContentProviderHolder getContentProvider(
IApplicationThread caller, String name, int userId, boolean stable) {
enforceNotIsolatedCaller("getContentProvider");
if (caller == null) {
String msg = "null IApplicationThread when getting content provider "
+ name;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
// The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
// 简单判断后直接调用了getContentProviderImpl函数
return getContentProviderImpl(caller, name, null, stable, userId);
}
ActivityManagerService.getContentProviderImpl函数分析
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
String name, IBinder token, boolean stable, int userId) {
// 每一个启动的或者请求还没有启动的ContentProvider对象在AMS中的记录
ContentProviderRecord cpr;
// ContentProvider和APP连接绑定的数据信息
ContentProviderConnection conn = null;
// 对应Provider的PKMS信息
ProviderInfo cpi = null;
synchronized (this) {
// 通过name查看AMS中是否存在对应的记录
cpr = mProviderMap.getProviderByName(name, userId);
boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
if (providerRunning) {
// provider运行
cpi = cpr.info;
if (r != null && cpr.canRunHere(r)) {
// provider进程存在 & provider进程和请求provider的进程是同一个进程直接返回
ContentProviderHolder holder = cpr.newHolder(null);
holder.provider = null;
return holder;
}
// 增加对应的provider的引用计数, 并且创建对应的ContentProviderConnection对象
conn = incProviderCountLocked(r, cpr, token, stable);
if (!providerRunning) {
// provider没有运行
try {
// 通过PKMS查找对应的ProviderInfo
cpi = AppGlobals.getPackageManager().
resolveContentProvider(name,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
} catch (RemoteException ex) {
}
if (cpi == null) {
return null;
}
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
// 通过ComponentName查看AMS中是否存在对应的记录
cpr = mProviderMap.getProviderByClass(comp, userId);
final boolean firstClass = cpr == null;
if (firstClass) {
// 创建ContentProviderRecord对象
cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
}
if (r != null && cpr.canRunHere(r)) {
return cpr.newHolder(null);
}
// mLaunchingProviders为等待启动的provides
final int N = mLaunchingProviders.size();
int i;
for (i = 0; i < N; i++) {
if (mLaunchingProviders.get(i) == cpr) {
break;
}
}
// If the provider is not already being launched, then get it
// started.
// 没有在等待启动的列表里面
if (i >= N) {
try {
// Content provider is now in use, its package can't be stopped.
// Use existing process if already started
// 检测当前对应的provide进程是否存在
checkTime(startTime, "getContentProviderImpl: looking for process record");
ProcessRecord proc = getProcessRecordLocked(
cpi.processName, cpr.appInfo.uid, false);
if (proc != null && proc.thread != null && !proc.killed) {
if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
"Installing in existing process " + proc);
if (!proc.pubProviders.containsKey(cpi.name)) {
checkTime(startTime, "getContentProviderImpl: scheduling install");
proc.pubProviders.put(cpi.name, cpr);
try {
// 通过binder回调ActivityThread的scheduleInstallProvider函数
proc.thread.scheduleInstallProvider(cpi);
} catch (RemoteException e) {
}
}
} else {
// 启动provide所在的app进程
proc = startProcessLocked(cpi.processName,
cpr.appInfo, false, 0, "content provider",
new ComponentName(cpi.applicationInfo.packageName,
cpi.name), false, false, false);
}
cpr.launchingApp = proc;
// 将cpr添加到mLaunchingProviders中
mLaunchingProviders.add(cpr);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
if (firstClass) {
// 记录到mProviderMap
mProviderMap.putProviderByClass(comp, cpr);
}
// 记录到mProviderMap
mProviderMap.putProviderByName(name, cpr);
// 增加对应的连接引用数
conn = incProviderCountLocked(r, cpr, token, stable);
if (conn != null) {
conn.waiting = true;
}
}
}
// Wait for the provider to be published...
// 等待provider启动完成
synchronized (cpr) {
while (cpr.provider == null) {
try {
if (conn != null) {
conn.waiting = true;
}
cpr.wait();
} catch (InterruptedException ex) {
} finally {
if (conn != null) {
conn.waiting = false;
}
}
}
}
// 返回ContentProviderHolder对象
return cpr != null ? cpr.newHolder(conn) : null;
}
}
ActivityManagerService.canRunHere函数分析
public boolean canRunHere(ProcessRecord app) {
// 判断provider和请求provider的进程是否是同一进程
return (info.multiprocess || info.processName.equals(app.processName))
&& uid == app.info.uid;
}
ActivityManagerService.incProviderCountLocked函数分析
ContentProviderConnection incProviderCountLocked(ProcessRecord r,
final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
if (r != null) {
for (int i=0; i<r.conProviders.size(); i++) {
ContentProviderConnection conn = r.conProviders.get(i);
if (conn.provider == cpr) {
if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
"Adding provider requested by "
+ r.processName + " from process "
+ cpr.info.processName + ": " + cpr.name.flattenToShortString()
+ " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
// 连接对象存在则增加相应的引用计数
if (stable) {
conn.stableCount++;
conn.numStableIncs++;
} else {
conn.unstableCount++;
conn.numUnstableIncs++;
}
return conn;
}
}
//创建对应的连接对象
ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
if (stable) {
conn.stableCount = 1;
conn.numStableIncs = 1;
} else {
conn.unstableCount = 1;
conn.numUnstableIncs = 1;
}
cpr.connections.add(conn);
r.conProviders.add(conn);
startAssociationLocked(r.uid, r.processName, r.curProcState,
cpr.uid, cpr.name, cpr.info.processName);
return conn;
}
cpr.addExternalProcessHandleLocked(externalProcessToken);
return null;
}
ActivityThread.installProvider函数分析
private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
ContentProvider localProvider = null;
IContentProvider provider;
if (holder == null || holder.provider == null) {
// AMS通过回调AcitivityThread的bindApplication接口时回去调用installContentProviders
// installContentProviders接口会走进来,然后通过AMS的publishContentProviders告知AMS provider启动完成
Context c = null;
ApplicationInfo ai = info.applicationInfo;
if (context.getPackageName().equals(ai.packageName)) {
c = context;
} else if (mInitialApplication != null &&
mInitialApplication.getPackageName().equals(ai.packageName)) {
c = mInitialApplication;
} else {
try {
c = context.createPackageContext(ai.packageName,
Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
}
}
try {
// 通过反射创建对应的provider对象
final java.lang.ClassLoader cl = c.getClassLoader();
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
// getIContentProvider为 ContentProvider的内部类Transport对象
// Transport继承ContentProviderNative对象,ContentProviderNative继承Binder又实现了IContentProvider接口
// Transport对应为IContentProvider的Binder本地对象
provider = localProvider.getIContentProvider();
// XXX Need to create the correct context for this provider.
// attachInfo最终调用对应provider的onCreate函数
localProvider.attachInfo(c, info);
} catch (java.lang.Exception e) {
if (!mInstrumentation.onException(null, e)) {
throw new RuntimeException(
"Unable to get provider " + info.name
+ ": " + e.toString(), e);
}
return null;
}
} else {
// 从AMS中获取的IContentProvider代理对象
provider = holder.provider;
if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
+ info.name);
}
ContentProviderHolder retHolder;
synchronized (mProviderMap) {
IBinder jBinder = provider.asBinder();
// 在APK进程中创建缓存对象
if (localProvider != null) {
ComponentName cname = new ComponentName(info.packageName, info.name);
ProviderClientRecord pr = mLocalProvidersByName.get(cname);
provider = pr.mProvider;
} else {
holder = new ContentProviderHolder(info);
holder.provider = provider;
holder.noReleaseNeeded = true;
// 创建ProviderClientRecord对象
pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
mLocalProviders.put(jBinder, pr);
mLocalProvidersByName.put(cname, pr);
}
retHolder = pr.mHolder;
} else {
// ProviderRefCount对象是否存在,不存在则创建
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
if (DEBUG_PROVIDER) {
Slog.v(TAG, "installProvider: lost the race, updating ref count");
}
if (!noReleaseNeeded) {
incProviderRefLocked(prc, stable);
try {
ActivityManager.getService().removeContentProvider(
holder.connection, stable);
} catch (RemoteException e) {
//do nothing content provider object is dead any way
}
}
} else {
ProviderClientRecord client = installProviderAuthoritiesLocked(
provider, localProvider, holder);
if (noReleaseNeeded) {
prc = new ProviderRefCount(holder, client, 1000, 1000);
} else {
prc = stable
? new ProviderRefCount(holder, client, 1, 0)
: new ProviderRefCount(holder, client, 0, 1);
}
mProviderRefCountMap.put(jBinder, prc);
}
retHolder = prc.holder;
}
return retHolder;
}
ContentProvider.java (frameworks\base\core\java\android\content)
ContentProvider.attachInfo函数分析
private void attachInfo(Context context, ProviderInfo info, boolean testing) {
mNoPerms = testing;
if (mContext == null) {
mContext = context;
if (context != null) {
mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(
Context.APP_OPS_SERVICE);
}
mMyUid = Process.myUid();
if (info != null) {
setReadPermission(info.readPermission);
setWritePermission(info.writePermission);
setPathPermissions(info.pathPermissions);
mExported = info.exported;
mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0;
setAuthorities(info.authority);
}
// 回调具体实现类的onCreate函数
ContentProvider.this.onCreate();
}
}
ContentResolver.java (frameworks\base\core\java\android\content)
ContentResolver.query函数分析
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable CancellationSignal cancellationSignal) {
Preconditions.checkNotNull(uri, "uri");
IContentProvider unstableProvider = acquireUnstableProvider(uri);
try {
// 调用IContentProvider代理对象的query函数 (ContentProviderProxy)
qCursor = unstableProvider.query(mPackageName, uri, projection,
queryArgs, remoteCancellationSignal);
} catch (DeadObjectException e) {
}
if (qCursor == null) {
return null;
}
// Wrap the cursor object into CursorWrapperInner object.
// 通过IBulkCursor和CursorWindow来处理数据,后面章节再来分析
final IContentProvider provider = (stableProvider != null) ? stableProvider
: acquireProvider(uri);
final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
stableProvider = null;
qCursor = null;
return wrapper;
}
ContentProviderNative.java (frameworks\base\core\java\android\content)
ContentProviderProxy代理对象通过Binder驱动调用ContentProviderNative的onTransact函数
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
try {
switch (code) {
case QUERY_TRANSACTION: {
// Transport的query函数Transport继承ContentProviderNative
Cursor cursor = query(callingPkg, url, projection, queryArgs, cancellationSignal);
}
}
}
}
ContentProvider.java (frameworks\base\core\java\android\content)
ContentProvider内部类Transport的query函数
public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
@Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
final String original = setCallingPackage(callingPkg);
try {
// 最终调用子类Provider的query函数,返回对应的Cursor对象
return ContentProvider.this.query(
uri, projection, queryArgs,
CancellationSignal.fromTransport(cancellationSignal));
} finally {
setCallingPackage(original);
}
}
ActivityThread.java (frameworks\base\core\java\android\app)
还有一个比较重要的函数需要分析下,ActivityThread的handleBindApplication,AMS通过startProcess函数启动APK进程,APK进程调用ActivityThread的attach函数
attach中函数中会去去调用AMS的attachApplication函数。attachApplication函数终又回过头来调用ActivityThread的bindApplication函数
private void handleBindApplication(AppBindData data) {
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
// 安装Providers
installContentProviders(app, data.providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
}
ActivityThread.installContentProviders函数分析
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
if (DEBUG_PROVIDER) {
StringBuilder buf = new StringBuilder(128);
buf.append("Pub ");
buf.append(cpi.authority);
buf.append(": ");
buf.append(cpi.name);
Log.i(TAG, buf.toString());
}
// installProvider之前分析过
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
// 向AMS提交providers安装完成
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
ActivityManagerService.java (frameworks\base\services\core\java\com\android\server\am)
ActivityManagerService::publishContentProviders函数分析
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
synchronized (this) {
final ProcessRecord r = getRecordForAppLocked(caller);
final int N = providers.size();
for (int i = 0; i < N; i++) {
ContentProviderHolder src = providers.get(i);
if (src == null || src.info == null || src.provider == null) {
continue;
}
// 获取对应的provider记录对象
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
if (dst != null) {
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProviderMap.putProviderByName(names[j], dst);
}
int launchingCount = mLaunchingProviders.size();
int j;
boolean wasInLaunchingProviders = false;
for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
// 从mLaunchingProviders中移除已经启动完成的provider
mLaunchingProviders.remove(j);
wasInLaunchingProviders = true;
j--;
launchingCount--;
}
}
if (wasInLaunchingProviders) {
// 将超时msg从队列中去掉
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
// 唤醒在getContentProviderImpl函数中等待的客户端进程
dst.notifyAll();
}
updateOomAdjLocked(r, true);
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
}
}
Binder.restoreCallingIdentity(origId);
}
}