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
}