(源码阅读)Resources资源加载流程


google加载资源的源码
    ImageView里面的Src图片属性,最终都是通过下面这行代码去加载的:
1
final TypedArray a = context.obtainStyledAttributes(
2
                attrs, R.styleable.ImageView, defStyleAttr, defStyleRes);
3
4
        final Drawable d = a.getDrawable(R.styleable.ImageView_src);//R.styleable.ImageView_src读取的就是我们在xml里面的ImageView下面设置的src属性
5
        if (d != null) {
6
            setImageDrawable(d);
7
        }

1
public Drawable getDrawable(@StyleableRes int index) {
2
        if (mRecycled) {
3
            throw new RuntimeException("Cannot make calls to a recycled instance!");
4
        }
5
6
        final TypedValue value = mValue;
7
        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
8
            if (value.type == TypedValue.TYPE_ATTRIBUTE) {
9
                throw new UnsupportedOperationException(
10
                        "Failed to resolve attribute at index " + index + ": " + value);
11
            }
12
            return mResources.loadDrawable(value, value.resourceId, mTheme);//主要是这行代码去Load资源
13
        }
14
        return null;
15
    }
这个时候我们需要去找mResources的实例对象,我们平时在Activity中使用的getResources(),点进去发现是抽象类,最后在AndroidSDK源码下找到 ContextImpl.java  文件,再搜索getResources()方法。
1
 @Override
2
    public Resources getResources() {
3
        return mResources;
4
    }
5
......
6
 mResources = resources;
一路方法跟进去,最后在 ResourcesManager下面发现了这样的代码
1
 final Resources resources;
2
            if (activityToken != null) {
3
                resources = getOrCreateResourcesForActivityLocked(activityToken, classLoader,
4
                        resourcesImpl);
5
            } else {
6
                resources = getOrCreateResourcesLocked(classLoader, resourcesImpl);
7
            }
8
            return resources;
9
10
Resources resources = new Resources(classLoader);
11
        resources.setImpl(impl);
12
        activityResources.activityResources.add(new WeakReference<>(resources));
13
        if (DEBUG) {
14
            Slog.d(TAG, "- creating new ref=" + resources);
15
            Slog.d(TAG, "- setting ref=" + resources + " with impl=" + impl);
16
        }
17
        return resources;
18
19
//Resources的另外一个构造方法,因为对类加载的机制不熟悉,虽然这个已经过时了,我们这里还是使用一下吧
20
/**
21
     * Create a new Resources object on top of an existing set of assets in an
22
     * AssetManager.
23
     *
24
     * @deprecated Resources should not be constructed by apps.
25
     * See {@link android.content.Context#createConfigurationContext(Configuration)}.
26
     *
27
     * @param assets Previously created AssetManager.
28
     * @param metrics Current display metrics to consider when
29
     *                selecting/computing resource values.
30
     * @param config Desired device configuration to consider when
31
     *               selecting/computing resource values (optional).
32
     */
33
 public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
34
        this(null);
35
        mResourcesImpl = new ResourcesImpl(assets, metrics, config, new DisplayAdjustments());
36
    }
37
这边就已经得到我们想要的如何去创建Resources对象的代码了。
总结:既然资源的加载是通过Resource类,如果想要去获取另外一个Apk中的资源是不是可以自己去实例化一个呢?所以我们在阅读的过程中只需要去找到如何去实例化Resouces对象的代码就可以了,怎么new的对象
Resources resources = new Resources(new AssetManager(),new DiaplayMetrics(),new Configuration());-->
AssetManager其实是Resources的核心实例--->最终是通过AssetManager去获取。
1
/**
2
     * Add an additional set of assets to the asset manager.  This can be
3
     * either a directory or ZIP file.  Not for use by applications.  Returns
4
     * the cookie of the added asset, or 0 on failure.
5
     * {@hide}也可以是一个Apk文件或者是一个Zip文件
6
     */
7
    public final int addAssetPath(String path) {
8
        return  addAssetPathInternal(path, false);
9
    }

猜你喜欢

转载自blog.csdn.net/guim_007/article/details/76472827
今日推荐