Resource()中的getDrawable(int id)是怎样将图片显示出来的

首先看Resources.java中的getDrawable(int id)方法的源码:
 public Drawable getDrawable(int id) throws NotFoundException {
        synchronized (mTmpValue) {
            TypedValue value = mTmpValue;
            getValue(id, value, true);
            return loadDrawable(value, id);
        }
    }
在这个方法中找到传入的id的值的图片并返回.
在这里我们可以看到该方法将id传给loadDrawable(value, id);同时传递的还有value,显然这个值是很关键的,看看这个值在这里起到怎样的作用
(1)final TypedValue mTmpValue = new TypedValue();
官方文档对这个类的解释:Container for a dynamically typed data value. Primarily used with Resources for holding resource values.
翻译:
一个动态地数据值的容器。 主要被Resouces使用于持有的资源值.我理解为存储数据类型
(2)getValue(id,value,true)
执行这个方法获取该id的资源的属性


 public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException {
        boolean found = mAssets.getResourceValue(id, outValue, resolveRefs);
        if (found) {
            return;
        }
        throw new NotFoundException("Resource ID #0x"+ Integer.toHexString(id));
    }
这里涉及的方法:
final AssetManager mAssets;
mAssets.getResourceValue(id, outValue, resolveRefs);
源码如下:
final boolean getResourceValue(int ident,TypedValue outValue,boolean resolveRefs){
        int block = loadResourceValue(ident, outValue, resolveRefs);
        if (block >= 0) {
            if (outValue.type != TypedValue.TYPE_STRING) {
                return true;
            }
            outValue.string = mStringBlocks[block].get(outValue.data);
            return true;
        }
        return false;
    }
涉及方法:
  /** Returns true if the resource was found, filling in mRetStringBlock andmRetData. */
    private native final int loadResourceValue(int ident, TypedValue outValue,boolean resolve);
我们已经将加载图片的方法到了底层的C代码,从源码的注释,我们可以看到
"如果资源被找到返回true,同时填补mRetStringBlock andmRetData"
也就是通过id号,我们应该已经拿到资源的属性,存放在value内,通过TypedValue中的方法和属性就可以获得我们想要的值.
在前面做了这么多的准备工作后,下面的源码就是我们实现的核心方法了,
Drawable loadDrawable(TypedValue value, int id)throws NotFoundException {
        if (TRACE_FOR_PRELOAD) {
            // Log only framework resources
            if ((id >>> 24) == 0x1) {
                final String name = getResourceName(id);
                if (name != null) android.util.Log.d("PreloadDrawable", name);
            }
        }
        final long key = (((long) value.assetCookie) << 32) | value.data;
        Drawable dr = getCachedDrawable(key);
        if (dr != null) {
            return dr;
        }
        Drawable.ConstantState cs = sPreloadedDrawables.get(key);
        if (cs != null) {
            dr = cs.newDrawable(this);
        } else {
            if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
                    value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
                dr = new ColorDrawable(value.data);
            }
            if (dr == null) {
                if (value.string == null) {//表示无资源
                    throw new NotFoundException( "Resource is not a Drawable (color or path): " + value);
                }
   //获取资源的名字
                String file = value.string.toString();
                if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie "
                        + value.assetCookie + ": " + file);
                if (file.endsWith(".xml")) {//解析xml文件,返回drawable
                    try {
                        XmlResourceParser rp = loadXmlResourceParser(
                                file, id, value.assetCookie, "drawable");
                        dr = Drawable.createFromXml(this, rp);
                        rp.close();
                    } catch (Exception e) {
                        NotFoundException rnf = new NotFoundException(
                            "File " + file + " from drawable resource ID #0x"
                            + Integer.toHexString(id));
                        rnf.initCause(e);
                        throw rnf;
                    }
                } else {
                    try {//获取外部资源Asset
                        InputStream is = mAssets.openNonAsset(value.assetCookie, file, AssetManager.ACCESS_STREAMING);
        //              System.out.println("Opened file " + file + ": " + is);
                        dr = Drawable.createFromResourceStream(this, value, is, file, null);                        is.close();
        //              System.out.println("Created stream: " + dr);
                    } catch (Exception e) {
                        NotFoundException rnf = new NotFoundException(
                            "File " + file + " from drawable resource ID #0x"
                            + Integer.toHexString(id));
                        rnf.initCause(e);
                        throw rnf;
                    }
                }
            }
        }
        if (dr != null) {
            dr.setChangingConfigurations(value.changingConfigurations);
            cs = dr.getConstantState();
            if (cs != null) {
                if (mPreloading) {
                    sPreloadedDrawables.put(key, cs);
                } else {
                    synchronized (mTmpValue) {
                        //Log.i(TAG, "Saving cached drawable @ #" +
                        //        Integer.toHexString(key.intValue())
                        //        + " in " + this + ": " + cs);                        mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
                    }
                }
            }
        }
        return dr;
    }
发布了134 篇原创文章 · 获赞 26 · 访问量 77万+

猜你喜欢

转载自blog.csdn.net/yw1688/article/details/54618688