案例
Settings.Secure.putInt(contentresolver, "test", 1);
注:代码来自为8.1系统
#代码跟踪:
frameworks/base/core/java/android/provider/Settings.java
public static boolean putInt(ContentResolver cr, String name, int value) {
return putIntForUser(cr, name, value, UserHandle.myUserId());
}
public static boolean putIntForUser(ContentResolver cr, String name, int value,
int userHandle) {
return putStringForUser(cr, name, Integer.toString(value), userHandle);
}
public static boolean putStringForUser(ContentResolver resolver, String name, String value,
int userHandle) {
return putStringForUser(resolver, name, value, null, false, userHandle);
}
public static boolean putStringForUser(@NonNull ContentResolver resolver,
@NonNull String name, @Nullable String value, @Nullable String tag,
boolean makeDefault, @UserIdInt int userHandle) {
······
return sNameValueCache.putStringForUser(resolver, name, value, tag,
makeDefault, userHandle);
}
public boolean putStringForUser(ContentResolver cr, String name, String value,
String tag, boolean makeDefault, final int userHandle) {
try {
······
IContentProvider cp = mProviderHolder.getProvider(cr);
cp.call(cr.getPackageName(), mCallSetCommand, name, arg);
} catch (RemoteException e) {
Log.w(TAG, "Can't set key " + name + " in " + mUri, e);
return false;
}
return true;
}
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/system");
private static final ContentProviderHolder sProviderHolder =
new ContentProviderHolder(CONTENT_URI);
private static final NameValueCache sNameValueCache = new NameValueCache(
CONTENT_URI,
CALL_METHOD_GET_SYSTEM,
CALL_METHOD_PUT_SYSTEM,
sProviderHolder);
public IContentProvider getProvider(ContentResolver contentResolver) {
synchronized (mLock) {
if (mContentProvider == null) {
mContentProvider = contentResolver
.acquireProvider(mUri.getAuthority());
}
return mContentProvider;
}
}
调用ContentResolver的实例对象:ContextImpl下的ApplicationContentResolver
frameworks/base/core/java/android/app/ContextImpl.java
protected IContentProvider acquireProvider(Context context, String auth) {
return mMainThread.acquireProvider(context,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), true);
}
frameworks/base/core/java/android/app/ActivityThread.java
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
// the same provider at the same time. When this happens, we want to ensure
// that the first one wins.
// Note that we cannot hold the lock while acquiring and installing the
// provider since it might take a long time to run and it could also potentially
// be re-entrant in the case where the provider is in the same process.
ContentProviderHolder holder = null;
try {
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;
}
// 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;
}
我们重点关注不存在的Provider的情况:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final ContentProviderHolder getContentProvider(
IApplicationThread caller, String name, int userId, boolean stable) {
······
return getContentProviderImpl(caller, name, null, stable, userId);
}
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
String name, IBinder token, boolean stable, int userId) {
······
if (!providerRunning) {
try {
checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
cpi = AppGlobals.getPackageManager().
resolveContentProvider(name,
STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
} catch (RemoteException ex) {
}
······
}
}
frameworks/base/services/core/java/com/android/server/pm/PakcageManagerService.java
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
······
//通过name找到PackageParser.Provider,而通过provider找到对应apk的PackageSetting
//到这里就明了通过name可以找到apk
synchronized (mPackages) {
final PackageParser.Provider provider = mProvidersByAuthority.get(name);
PackageSetting ps = provider != null
? mSettings.mPackages.get(provider.owner.packageName)
: null;
}
}
网友评论