package com.glview.content.res; import java.io.InputStream; import android.content.res.AssetManager; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.util.SparseArray; import android.util.TypedValue; import com.glview.graphics.drawable.ColorDrawable; import com.glview.graphics.drawable.Drawable; import com.glview.graphics.drawable.Drawable.ConstantState; public class GLResources { private static final SparseArray<ConstantState> sCacheDrawables = new SparseArray<ConstantState>(); private static final byte[] sAccessLock = new byte[0]; AssetManager mAssets; Resources mAndroidResources; private TypedValue mTmpValue = new TypedValue(); public GLResources(AssetManager assets, Resources androidResources) { mAssets = assets; mAndroidResources = androidResources; } public Drawable getDrawable(int id) { if (id <= 0) return null; synchronized (sAccessLock) { Drawable dr = null; ConstantState cs = sCacheDrawables.get(id); if (cs != null) { dr = cs.newDrawable(mAndroidResources); return dr; } TypedValue value = mTmpValue; mAndroidResources.getValue(id, value, true); dr = loadDrawable(value, id); return dr; } } /*package*/ Drawable loadDrawable(TypedValue value, int id) throws NotFoundException { final boolean isColorDrawable; if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && value.type <= TypedValue.TYPE_LAST_COLOR_INT) { isColorDrawable = true; } else { isColorDrawable = false; } final Drawable dr; if (isColorDrawable) { dr = new ColorDrawable(value.data); } else { dr = loadDrawableInner(value, id); } if (dr != null) { dr.setChangingConfigurations(value.changingConfigurations); cacheDrawable(id, dr); } return dr; } private Drawable loadDrawableInner(TypedValue value, int id) throws NotFoundException { if (value.string == null) { throw new NotFoundException("Resource \"" + mAndroidResources.getResourceName(id) + "\" (" + Integer.toHexString(id) + ") is not a Drawable (color or path): " + value); } final String file = value.string.toString(); final Drawable dr; try { if (file.endsWith(".xml")) { final XmlResourceParser rp = mAssets.openXmlResourceParser(file); dr = Drawable.createFromXml(mAndroidResources, rp); rp.close(); } else { final InputStream is = mAssets.openNonAssetFd(file).createInputStream(); dr = Drawable.createFromResourceStream(mAndroidResources, value, is, file, null, true); is.close(); } } catch (Exception e) { final NotFoundException rnf = new NotFoundException( "File " + file + " from drawable resource ID #0x" + Integer.toHexString(id)); rnf.initCause(e); throw rnf; } return dr; } private void cacheDrawable(int id, Drawable dr) { ConstantState cs = dr.getConstantState(); if (cs == null) { return; } sCacheDrawables.put(id, cs); } /** * This exception is thrown by the resource APIs when a requested resource * can not be found. */ public static class NotFoundException extends RuntimeException { /** * */ private static final long serialVersionUID = -8449329176119403199L; public NotFoundException() { } public NotFoundException(String name) { super(name); } } }