美文网首页Android进化
Android frameworks中的Settings.jav

Android frameworks中的Settings.jav

作者: 锄禾豆 | 来源:发表于2019-10-15 13:05 被阅读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;
             }
    }
    

    相关文章

      网友评论

        本文标题:Android frameworks中的Settings.jav

        本文链接:https://www.haomeiwen.com/subject/nmfsmctx.html