首先了解一下Google加载资源源码
效果图
ImageView中加载src源码
final Drawable d = a.getDrawable(R.styleable.ImageView_src);
getDrawable源码
if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
if (value.type == TypedValue.TYPE_ATTRIBUTE) {
throw new UnsupportedOperationException(
"Failed to resolve attribute at index " + index + ": " + value);
}
return mResources.loadDrawable(value, value.resourceId, mTheme);
}
可以看到最终调用Resource中的loadDrawable方法
我们都知道我们可以通过代码getResource去加载资源,那么getResource是怎么加载的呢?
获取getResources源码,目的了解获取resource怎么去实例化的,一步一步走下去
@Override
public Resources getResources() {
return mBase.getResources();
}
发现调用的Content中的抽象方法getResource方法
查看Context的实现类ContextImpl中的getResource的方法
@Override
public Resources getResources() {
return mResources;
}
查看mResource怎么被赋值的
mResources = resources;
Resources resources = packageInfo.getResources(mainThread);
getResource源码
public Resources getResources(ActivityThread mainThread) {
if (mResources == null) {
mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs,
mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, this);
}
return mResources;
}
查看ActivityThread中getTopLevelResources源码
Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
String[] libDirs, int displayId, Configuration overrideConfiguration,
LoadedApk pkgInfo) {
return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs,
displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
}
查看ResourceManager中getTopLevelResources源码
//实际最终是new出来的一个对象
r = new Resources(assets, dm, config, compatInfo, token);
AssetManager assets = new AssetManager();
if (resDir != null) {
if (assets.addAssetPath(resDir) == 0) {
return null;
}
}
资源加载的总结:所有的资源加载通过Resource -> 构建对象是直接new的对象 -> AssetManager 其实是Resource的核心实例 -> 最终是通过AssetManager获取,然后通过addAssetPath将路径加载进去
案例:首先我们准备资源的apk,修改apk名字为meinv.skin:保存到本地手机中,我这里是直接拖到虚拟机/Download目录下的
代码很简单,直接粘贴了,注意源码中有{@hide}代表不能直接new必须通过反射获取实例
public void onClick(View view){
Resources superResource = getResources();
try {
AssetManager assets = AssetManager.class.newInstance();//{@hide}
Method method = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
method.invoke(assets, Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "Download"+File.separator+"meinv.skin");
Resources resources = new Resources
(assets, superResource.getDisplayMetrics(), superResource.getConfiguration());
//获得资源的id
int resourceId = resources.getIdentifier("image_src", "drawable", "com.hbwj.kanyuanma");
Drawable drawable = resources.getDrawable(resourceId);
skin_imageView.setImageDrawable(drawable);
} catch (Exception e) {
e.printStackTrace();
}
}