Android进化

Android frameworks中的Settings.jav

2019-10-15  本文已影响0人  锄禾豆

案例

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;
         }
}
上一篇下一篇

猜你喜欢

热点阅读