getResources()详解

getResources()详解/***Return<code>getActivity().getResources()</code>.*/finalpublicResourcesgetResources(){if(mHost==null){thrownewIllegalStateException("Fragment"+this…


/**
 * Return <code>getActivity().getResources()</code>.
 */
final public Resources getResources() {
    if (mHost == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to Activity");
    }
    return mHost.getContext().getResources();
}
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
class HostCallbacks extends FragmentHostCallback<FragmentActivity> {
    public HostCallbacks() {
        super(FragmentActivity.this /*fragmentActivity*/);
    }
}

mHost 是 FragmentHostCallback() 是在FragmentActivity 时候初始化的传给FragmentHostCallback() 并执行四个参数的构造方法 分别给mActivity 赋值,将mActivity强转 mContext并赋值mContext,获取mActivity的mHandler并赋值给mHandler,第四个参数是0。mHost的 getContext()就是调用Activity的mContext。getResources就是调用Activity的 getResources

public abstract class Context {
       public abstract Resources getResources();
}

我之前文章说过 Context 的具体实现类是ContextImpl,我们看下ContextImpl 的getResources是怎么实现的,

@Override
public Resources getResources() {
    return mResources;
}

直接返回一个mResources ,在看下mResources是哪里赋值的

private ContextImpl(ContextImpl container, ActivityThread mainThread,
        LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags,
        Display display, Configuration overrideConfiguration, int createDisplayWithId) {
    mOuterContext = this;

    mMainThread = mainThread;
    mActivityToken = activityToken;
    mFlags = flags;

    if (user == null) {
        user = Process.myUserHandle();
    }
    mUser = user;

    mPackageInfo = packageInfo;
    mResourcesManager = ResourcesManager.getInstance();
   // 获取 resources
    Resources resources = packageInfo.getResources(mainThread);
    // mResources 赋值
    mResources = resources;

    mDisplay = (createDisplayWithId == Display.INVALID_DISPLAY) ? display
            : mResourcesManager.getAdjustedDisplay(displayId,      mResources.getDisplayAdjustments());

 
}

我之前文章也讲过,ContextImpl创建是在 ActivityThread 创建时调用getSystemContext方法进行创建的

public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}
static ContextImpl createSystemContext(ActivityThread mainThread) {
    创建LoadedApk
    LoadedApk packageInfo = new LoadedApk(mainThread);
    创建ContextImpl
    ContextImpl context = new ContextImpl(null, mainThread,
            packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    return context;
}

我们在回到getResources方法 ,上面看到 packageInfo.getResources(mainThread); packageInfo就是LoadedApk这里在看下LoadedApk的getResources是如何实现的

public Resources getResources(ActivityThread mainThread) {
    if (mResources == null) {
        mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs,
                mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, this);
    }
    return mResources;
}

mResources 是通过 ActivityThread的getTopLevelResources方法获取的

Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
        String[] libDirs, int displayId, LoadedApk pkgInfo) {
    return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
            displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader());
}

这里是 mResourcesManager 的getResources方法

public @NonNull Resources getResources(@Nullable IBinder activityToken,
        @Nullable String resDir,
        @Nullable String[] splitResDirs,
        @Nullable String[] overlayDirs,
        @Nullable String[] libDirs,
        int displayId,
        @Nullable Configuration overrideConfig,
        @NonNull CompatibilityInfo compatInfo,
        @Nullable ClassLoader classLoader) {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#getResources");
        final ResourcesKey key = new ResourcesKey(
                resDir,
                splitResDirs,
                overlayDirs,
                libDirs,
                displayId,
                overrideConfig != null ? new Configuration(overrideConfig) : null, // Copy
                compatInfo);
        classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
        return getOrCreateResources(activityToken, key, classLoader);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
    }
}
private @NonNull Resources getOrCreateResources(@Nullable IBinder activityToken,
        @NonNull ResourcesKey key, @NonNull ClassLoader classLoader) {
    synchronized (this) {
        if (DEBUG) {
            Throwable here = new Throwable();
            here.fillInStackTrace();
            Slog.w(TAG, "!! Get resources for activity=" + activityToken + " key=" + key, here);
        }

        if (activityToken != null) {
            final ActivityResources activityResources =
                    getOrCreateActivityResourcesStructLocked(activityToken);

            // Clean up any dead references so they don't pile up.
            ArrayUtils.unstableRemoveIf(activityResources.activityResources,
                    sEmptyReferencePredicate);

            // Rebase the key's override config on top of the Activity's base override.
            if (key.hasOverrideConfiguration()
                    && !activityResources.overrideConfig.equals(Configuration.EMPTY)) {
                final Configuration temp = new Configuration(activityResources.overrideConfig);
                temp.updateFrom(key.mOverrideConfiguration);
                key.mOverrideConfiguration.setTo(temp);
            }

            ResourcesImpl resourcesImpl = findResourcesImplForKeyLocked(key);
            if (resourcesImpl != null) {
                if (DEBUG) {
                    Slog.d(TAG, "- using existing impl=" + resourcesImpl);
                }
                return getOrCreateResourcesForActivityLocked(activityToken, classLoader,
                        resourcesImpl);
            }

            // We will create the ResourcesImpl object outside of holding this lock.

        } else {
            // Clean up any dead references so they don't pile up.
            ArrayUtils.unstableRemoveIf(mResourceReferences, sEmptyReferencePredicate);

            // Not tied to an Activity, find a shared Resources that has the right ResourcesImpl
            ResourcesImpl resourcesImpl = findResourcesImplForKeyLocked(key);
            if (resourcesImpl != null) {
                if (DEBUG) {
                    Slog.d(TAG, "- using existing impl=" + resourcesImpl);
                }
                return getOrCreateResourcesLocked(classLoader, resourcesImpl);
            }

            // We will create the ResourcesImpl object outside of holding this lock.
        }
    }

    // If we're here, we didn't find a suitable ResourcesImpl to use, so create one now.
    ResourcesImpl resourcesImpl = createResourcesImpl(key);

    synchronized (this) {
        ResourcesImpl existingResourcesImpl = findResourcesImplForKeyLocked(key);
        if (existingResourcesImpl != null) {
            if (DEBUG) {
                Slog.d(TAG, "- got beat! existing impl=" + existingResourcesImpl
                        + " new impl=" + resourcesImpl);
            }
            resourcesImpl.getAssets().close();
            resourcesImpl = existingResourcesImpl;
        } else {
            // Add this ResourcesImpl to the cache.
            mResourceImpls.put(key, new WeakReference<>(resourcesImpl));
        }

        final Resources resources;
        if (activityToken != null) {
            resources = getOrCreateResourcesForActivityLocked(activityToken, classLoader,
                    resourcesImpl);
        } else {
            resources = getOrCreateResourcesLocked(classLoader, resourcesImpl);
        }
        return resources;
    }
}

 

 

今天的文章getResources()详解分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/25706.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注