Resources.java revision e5b50a65ad26a32f6e58588ffdcbc0389eac9257
1ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa/* 2ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Copyright (C) 2006 The Android Open Source Project 3ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 4ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Licensed under the Apache License, Version 2.0 (the "License"); 5ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * you may not use this file except in compliance with the License. 6ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * You may obtain a copy of the License at 7ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 8ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * http://www.apache.org/licenses/LICENSE-2.0 9ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 10ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Unless required by applicable law or agreed to in writing, software 11ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * distributed under the License is distributed on an "AS IS" BASIS, 12ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * See the License for the specific language governing permissions and 14ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * limitations under the License. 15ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 16ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 17ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaapackage android.content.res; 18ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 19a62050d42c7d76d57ae555ffcb6d8efc5cf79de1destradaaimport com.android.internal.util.XmlUtils; 20ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 21ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport org.xmlpull.v1.XmlPullParser; 22ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport org.xmlpull.v1.XmlPullParserException; 23ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 24ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.content.pm.ActivityInfo; 25ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.graphics.Movie; 26ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.graphics.drawable.Drawable; 27ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.graphics.drawable.ColorDrawable; 28ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.graphics.drawable.Drawable.ConstantState; 29a62050d42c7d76d57ae555ffcb6d8efc5cf79de1destradaaimport android.os.Build; 30ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.os.Bundle; 31ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.util.AttributeSet; 32ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.util.DisplayMetrics; 332102dd725540bcf51bf324a2775fbcffe45dd32fdestradaaimport android.util.Log; 34ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.util.Slog; 352102dd725540bcf51bf324a2775fbcffe45dd32fdestradaaimport android.util.TypedValue; 362102dd725540bcf51bf324a2775fbcffe45dd32fdestradaaimport android.util.LongSparseArray; 37ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 3881cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaaimport java.io.IOException; 39ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport java.io.InputStream; 40ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport java.lang.ref.WeakReference; 41ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport java.util.Locale; 422102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 43ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport libcore.icu.NativePluralRules; 44ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 45ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa/** 46ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Class for accessing an application's resources. This sits on top of the 47ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * asset manager of the application (accessible through {@link #getAssets}) and 48ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * provides a high-level API for getting typed data from the assets. 49ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 50ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>The Android resource system keeps track of all non-code assets associated with an 51ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * application. You can use this class to access your application's resources. You can generally 52ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * acquire the {@link android.content.res.Resources} instance associated with your application 532102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * with {@link android.content.Context#getResources getResources()}.</p> 5452617bbff8607cdc208ba107ec111bd1471433cbTsuwei Chen * 552102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <p>The Android SDK tools compile your application's resources into the application binary 56ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * at build time. To use a resource, you must install it correctly in the source tree (inside 57ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * your project's {@code res/} directory) and build your application. As part of the build 582102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * process, the SDK tools generate symbols for each resource, which you can use in your application 59ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * code to access the resources.</p> 60ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 61ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>Using application resources makes it easy to update various characteristics of your 62ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * application without modifying code, and—by providing sets of alternative 63ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resources—enables you to optimize your application for a variety of device configurations 64ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * (such as for different languages and screen sizes). This is an important aspect of developing 65ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Android applications that are compatible on different types of devices.</p> 66ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 67ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>For more information about using resources, see the documentation about <a 682102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.</p> 692102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 702102dd725540bcf51bf324a2775fbcffe45dd32fdestradaapublic class Resources { 712102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa static final String TAG = "Resources"; 722102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final boolean DEBUG_LOAD = false; 732102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final boolean DEBUG_CONFIG = false; 742102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final boolean DEBUG_ATTRIBUTES_CACHE = false; 752102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final boolean TRACE_FOR_PRELOAD = false; 762102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final boolean TRACE_FOR_MISS_PRELOAD = false; 772102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 782102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final int ID_OTHER = 0x01000004; 792102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 802102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final Object sSync = new Object(); 812102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /*package*/ static Resources mSystem = null; 822102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 832102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // Information about preloaded resources. Note that they are not 842102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // protected by a lock, because while preloading in zygote we are all 852102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // single-threaded, and after that these are immutable. 862102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final LongSparseArray<Drawable.ConstantState> sPreloadedDrawables 87ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa = new LongSparseArray<Drawable.ConstantState>(); 88ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private static final LongSparseArray<ColorStateList> sPreloadedColorStateLists 89ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa = new LongSparseArray<ColorStateList>(); 902102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables 91ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa = new LongSparseArray<Drawable.ConstantState>(); 92ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private static boolean sPreloaded; 93ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private static int sPreloadedDensity; 94ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 952102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // These are protected by mAccessLock. 96ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 97ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ final Object mAccessLock = new Object(); 98ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ final Configuration mTmpConfig = new Configuration(); 99ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ TypedValue mTmpValue = new TypedValue(); 1002102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache 101ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa = new LongSparseArray<WeakReference<Drawable.ConstantState> >(); 102ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache 103ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa = new LongSparseArray<WeakReference<ColorStateList> >(); 104ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache 1052102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa = new LongSparseArray<WeakReference<Drawable.ConstantState> >(); 106ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ boolean mPreloading; 107ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 108ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /*package*/ TypedArray mCachedStyledAttributes = null; 109ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa RuntimeException mLastRetrievedAttrs = null; 1102102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 111ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private int mLastCachedXmlBlockIndex = -1; 112ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private final int[] mCachedXmlBlockIds = { 0, 0, 0, 0 }; 113ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[4]; 114ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1152102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /*package*/ final AssetManager mAssets; 1162102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private final Configuration mConfiguration = new Configuration(); 1172102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics(); 1182102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private NativePluralRules mPluralRule; 1192102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1202102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private CompatibilityInfo mCompatibilityInfo; 1212102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1222102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** @hide */ 1232102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public static int selectDefaultTheme(int curTheme, int targetSdkVersion) { 1242102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return selectSystemTheme(curTheme, targetSdkVersion, 1252102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa com.android.internal.R.style.Theme, 1262102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa com.android.internal.R.style.Theme_Holo, 1272102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa com.android.internal.R.style.Theme_DeviceDefault); 1282102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1292102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1302102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** @hide */ 1312102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public static int selectSystemTheme(int curTheme, int targetSdkVersion, 1322102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int orig, int holo, int deviceDefault) { 1332102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (curTheme != 0) { 1342102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return curTheme; 1352102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1362102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) { 1372102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return orig; 1382102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1392102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 1402102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return holo; 1412102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1422102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return deviceDefault; 1432102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1442102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1452102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 1462102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * This exception is thrown by the resource APIs when a requested resource 1472102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * can not be found. 1482102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 1492102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public static class NotFoundException extends RuntimeException { 1502102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public NotFoundException() { 1512102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1522102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1532102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public NotFoundException(String name) { 1542102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa super(name); 1552102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1562102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 1572102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1582102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 1592102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Create a new Resources object on top of an existing set of assets in an 1602102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * AssetManager. 161ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 162ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param assets Previously created AssetManager. 163ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param metrics Current display metrics to consider when 164ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * selecting/computing resource values. 1652102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param config Desired device configuration to consider when 166ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * selecting/computing resource values (optional). 167ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 168ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) { 169ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa this(assets, metrics, config, null); 170ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 171ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1722102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 173ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Creates a new Resources object with CompatibilityInfo. 1742102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1752102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param assets Previously created AssetManager. 176ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param metrics Current display metrics to consider when 17781cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * selecting/computing resource values. 178ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param config Desired device configuration to consider when 179ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * selecting/computing resource values (optional). 180ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param compInfo this resource's compatibility info. It will use the default compatibility 181ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * info when it's null. 1822102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @hide 183ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 184ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public Resources(AssetManager assets, DisplayMetrics metrics, 185ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Configuration config, CompatibilityInfo compInfo) { 186ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mAssets = assets; 187ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mMetrics.setToDefaults(); 188ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mCompatibilityInfo = compInfo; 189ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa updateConfiguration(config, metrics); 190ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa assets.ensureStringBlocks(); 191ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 192ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 193ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 194ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a global shared Resources object that provides access to only 195ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * system resources (no application resources), and is not configured for 1962102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * the current screen (can not use dimension units, does not change based 197ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * on orientation, etc). 198ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 199ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public static Resources getSystem() { 200ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (sSync) { 201ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Resources ret = mSystem; 202ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (ret == null) { 203ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa ret = new Resources(); 204ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mSystem = ret; 205ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 206ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 207ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return ret; 208ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 209ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 210ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 211ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 2122102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return the string value associated with a particular resource ID. The 213ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * returned object will be a String if this is a plain string; it will be 214ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * some other type of CharSequence if it is styled. 215ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@more} 216ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 217ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 218ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 219ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 220ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 221ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 222ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 223ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return CharSequence The string data associated with the resource, plus 224ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * possibly styled text information. 225ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 226ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public CharSequence getText(int id) throws NotFoundException { 227ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa CharSequence res = mAssets.getResourceText(id); 228ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (res != null) { 229ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 230ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 2312102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa throw new NotFoundException("String resource ID #0x" 2322102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa + Integer.toHexString(id)); 2332102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2342102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 2352102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 2362102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return the character sequence associated with a particular resource ID for a particular 2372102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * numerical quantity. 2382102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 2392102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <p>See <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String 2402102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Resources</a> for more on quantity strings. 2412102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 2422102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 2432102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 2442102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * entry. The value 0 is an invalid identifier. 2452102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param quantity The number used to get the correct string for the current language's 2462102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * plural rules. 2472102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 2482102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 2492102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 2502102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return CharSequence The string data associated with the resource, plus 2512102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * possibly styled text information. 2522102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 2532102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public CharSequence getQuantityText(int id, int quantity) throws NotFoundException { 2542102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa NativePluralRules rule = getPluralRule(); 2552102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa CharSequence res = mAssets.getResourceBagText(id, 2562102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa attrForQuantityCode(rule.quantityForInt(quantity))); 257ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (res != null) { 2582102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return res; 2592102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 260ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa res = mAssets.getResourceBagText(id, ID_OTHER); 261ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (res != null) { 262ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 2632102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 264ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("Plural resource ID #0x" + Integer.toHexString(id) 2652102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa + " quantity=" + quantity 2662102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa + " item=" + stringForQuantityCode(rule.quantityForInt(quantity))); 2672102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2682102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 2692102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private NativePluralRules getPluralRule() { 2702102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa synchronized (sSync) { 2712102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (mPluralRule == null) { 2722102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa mPluralRule = NativePluralRules.forLocale(mConfiguration.locale); 2732102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2742102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return mPluralRule; 2752102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2762102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2772102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 2782102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static int attrForQuantityCode(int quantityCode) { 279ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa switch (quantityCode) { 280ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa case NativePluralRules.ZERO: return 0x01000005; 281ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa case NativePluralRules.ONE: return 0x01000006; 2822102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.TWO: return 0x01000007; 2832102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.FEW: return 0x01000008; 2842102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.MANY: return 0x01000009; 2852102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa default: return ID_OTHER; 2862102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2872102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2882102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 2892102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa private static String stringForQuantityCode(int quantityCode) { 2902102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa switch (quantityCode) { 2912102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.ZERO: return "zero"; 2922102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.ONE: return "one"; 2932102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.TWO: return "two"; 2942102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.FEW: return "few"; 2952102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa case NativePluralRules.MANY: return "many"; 2962102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa default: return "other"; 2972102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2982102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 2992102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 3002102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 3012102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return the string value associated with a particular resource ID. It 3022102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * will be stripped of any styled text information. 3032102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * {@more} 304ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 3052102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 3062102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 3072102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * entry. The value 0 is an invalid identifier. 3082102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 3092102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 3102102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 3112102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return String The string data associated with the resource, 312ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * stripped of styled text information. 313ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 314ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public String getString(int id) throws NotFoundException { 315ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa CharSequence res = getText(id); 316ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (res != null) { 317ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res.toString(); 318ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 319ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("String resource ID #0x" 320ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 321ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 322ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 323ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 324ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 32581cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * Return the string value associated with a particular resource ID, 32681cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * substituting the format arguments as defined in {@link java.util.Formatter} 32781cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * and {@link java.lang.String#format}. It will be stripped of any styled text 32881cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * information. 32981cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * {@more} 33081cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * 33181cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * @param id The desired resource identifier, as generated by the aapt 33281cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * tool. This integer encodes the package, type, and resource 33381cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * entry. The value 0 is an invalid identifier. 33481cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * 33581cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * @param formatArgs The format arguments that will be used for substitution. 33681cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * 33781cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 33881cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * 339ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return String The string data associated with the resource, 340ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * stripped of styled text information. 341ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 342ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public String getString(int id, Object... formatArgs) throws NotFoundException { 343ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa String raw = getString(id); 344ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return String.format(mConfiguration.locale, raw, formatArgs); 345ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 346ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 347ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 348ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return the string value associated with a particular resource ID for a particular 349ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * numerical quantity, substituting the format arguments as defined in 350ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link java.util.Formatter} and {@link java.lang.String#format}. It will be 351ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * stripped of any styled text information. 352ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@more} 353ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 354ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>See <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String 355ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Resources</a> for more on quantity strings. 356ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 357ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 358ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 359ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 360ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param quantity The number used to get the correct string for the current language's 361ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * plural rules. 362ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param formatArgs The format arguments that will be used for substitution. 363ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 364ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 365ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 366ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return String The string data associated with the resource, 367ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * stripped of styled text information. 368ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 369ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public String getQuantityString(int id, int quantity, Object... formatArgs) 370ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throws NotFoundException { 371ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa String raw = getQuantityText(id, quantity).toString(); 372ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return String.format(mConfiguration.locale, raw, formatArgs); 373ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 374ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 375ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 376ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return the string value associated with a particular resource ID for a particular 377ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * numerical quantity. 378ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 379ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>See <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String 380ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Resources</a> for more on quantity strings. 381ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 382ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 383ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 384ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 385ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param quantity The number used to get the correct string for the current language's 3862102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * plural rules. 3872102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 3882102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 3892102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 3902102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return String The string data associated with the resource, 3912102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * stripped of styled text information. 3922102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 3932102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public String getQuantityString(int id, int quantity) throws NotFoundException { 3942102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return getQuantityText(id, quantity).toString(); 3952102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 3962102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 3972102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 3982102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return the string value associated with a particular resource ID. The 3992102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * returned object will be a String if this is a plain string; it will be 4002102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * some other type of CharSequence if it is styled. 4012102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4022102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 4032102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 4042102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * entry. The value 0 is an invalid identifier. 4052102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4062102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param def The default CharSequence to return. 4072102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4082102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return CharSequence The string data associated with the resource, plus 4092102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * possibly styled text information, or def if id is 0 or not found. 4102102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 4112102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public CharSequence getText(int id, CharSequence def) { 4122102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa CharSequence res = id != 0 ? mAssets.getResourceText(id) : null; 4132102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return res != null ? res : def; 4142102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 4152102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 4162102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 4172102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return the styled text array associated with a particular resource ID. 4182102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4192102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 4202102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 4212102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * entry. The value 0 is an invalid identifier. 4222102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4232102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 4242102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4252102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return The styled text array associated with the resource. 4262102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 4272102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public CharSequence[] getTextArray(int id) throws NotFoundException { 4282102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa CharSequence[] res = mAssets.getResourceTextArray(id); 4292102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (res != null) { 4302102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return res; 4312102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 432ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("Text array resource ID #0x" 433ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 4342102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 4352102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 436ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 437ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return the string array associated with a particular resource ID. 438ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 439ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 440ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 441ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 442ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 443ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 444ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 445ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return The string array associated with the resource. 446ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 447ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public String[] getStringArray(int id) throws NotFoundException { 448ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa String[] res = mAssets.getResourceStringArray(id); 449ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (res != null) { 450ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 451ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 452ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("String array resource ID #0x" 453ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 454ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 455ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 456ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 457ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return the int array associated with a particular resource ID. 4582102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 4592102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 460ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 461ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 462ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 463ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 464ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 465ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return The int array associated with the resource. 466ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 467ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public int[] getIntArray(int id) throws NotFoundException { 468ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int[] res = mAssets.getArrayIntResource(id); 4692102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (res != null) { 470ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 471ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 472ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("Int array resource ID #0x" 473ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 474ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 475ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 476ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 477ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return an array of heterogeneous values. 478ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 479ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 480ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 481ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 482ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 483ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 484ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 485ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Returns a TypedArray holding an array of the array values. 4862102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} 487ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * when done with it. 488ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 489ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public TypedArray obtainTypedArray(int id) throws NotFoundException { 490ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int len = mAssets.getArraySize(id); 491ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (len < 0) { 492ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("Array resource ID #0x" 493ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 4942102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 495ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 496ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedArray array = getCachedStyledAttributes(len); 497ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa array.mLength = mAssets.retrieveArray(id, array.mData); 498ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa array.mIndices[0] = 0; 499ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 500ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return array; 501ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 5022102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 503ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 504ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Retrieve a dimensional for a particular resource ID. Unit 505ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * conversions are based on the current {@link DisplayMetrics} associated 506ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * with the resources. 507ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 508ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 509ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 510ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 511ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 512ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Resource dimension value multiplied by the appropriate 513ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * metric. 514ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 515ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 516ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 517ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getDimensionPixelOffset 518ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getDimensionPixelSize 519ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 5202102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public float getDimension(int id) throws NotFoundException { 521ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 522ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value = mTmpValue; 523ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 524ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value = new TypedValue(); 525ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 526ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 527ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type == TypedValue.TYPE_DIMENSION) { 5282102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return TypedValue.complexToDimension(value.data, mMetrics); 529ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 530ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 531ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 532ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(value.type) + " is not valid"); 533ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 534ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 535ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 5362102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 537ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Retrieve a dimensional for a particular resource ID for use 538ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * as an offset in raw pixels. This is the same as 539ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link #getDimension}, except the returned value is converted to 540ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * integer pixels for you. An offset conversion involves simply 541ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * truncating the base value to an integer. 542ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 543ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 544ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 545ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 546ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 547ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Resource dimension value multiplied by the appropriate 548ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * metric and truncated to integer pixels. 549ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 550ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 551ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 552ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getDimension 553ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getDimensionPixelSize 554ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 5552102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public int getDimensionPixelOffset(int id) throws NotFoundException { 556ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 557ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value = mTmpValue; 558ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 559ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value = new TypedValue(); 560ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 561ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 562ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type == TypedValue.TYPE_DIMENSION) { 5632102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return TypedValue.complexToDimensionPixelOffset( 564ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.data, mMetrics); 565ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 566ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 567ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 568ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(value.type) + " is not valid"); 569ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 570ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 5712102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 572ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 573ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Retrieve a dimensional for a particular resource ID for use 574ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * as a size in raw pixels. This is the same as 575ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link #getDimension}, except the returned value is converted to 576ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * integer pixels for use as a size. A size conversion involves 577ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * rounding the base value, and ensuring that a non-zero base value 578ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * is at least one pixel in size. 579ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 580ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 581ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 582ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 583ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 584ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Resource dimension value multiplied by the appropriate 585ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * metric and truncated to integer pixels. 586ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 587ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 5882102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 589ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getDimension 590ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getDimensionPixelOffset 591ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 592ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public int getDimensionPixelSize(int id) throws NotFoundException { 593ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 594ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value = mTmpValue; 595ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 5962102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa mTmpValue = value = new TypedValue(); 597ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 598ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 599ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type == TypedValue.TYPE_DIMENSION) { 600ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return TypedValue.complexToDimensionPixelSize( 601ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.data, mMetrics); 602ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 603ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 6042102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 605ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(value.type) + " is not valid"); 606ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 607ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 608ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 609ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 610ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Retrieve a fractional unit for a particular resource ID. 611ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 612ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 613ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 614ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 615ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param base The base value of this fraction. In other words, a 616ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * standard fraction is multiplied by this value. 617ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param pbase The parent base value of this fraction. In other 618ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * words, a parent fraction (nn%p) is multiplied by this 619ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * value. 620ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 6212102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return Attribute fractional value multiplied by the appropriate 622ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * base value. 623ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 624ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 625ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 626ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public float getFraction(int id, int base, int pbase) { 627ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 628ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value = mTmpValue; 6292102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (value == null) { 630ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value = new TypedValue(); 631ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 632ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 633ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type == TypedValue.TYPE_FRACTION) { 634ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return TypedValue.complexToFraction(value.data, base, pbase); 635ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 636ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 6372102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 638ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(value.type) + " is not valid"); 639ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 640ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 641ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 642ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 643ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a drawable object associated with a particular resource ID. 644ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Various types of objects will be returned depending on the underlying 645ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resource -- for example, a solid color, PNG image, scalable image, etc. 646ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * The Drawable API hides these implementation details. 647ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 648ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p class="note"><strong>Note:</strong> Prior to 649ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link android.os.Build.VERSION_CODES#JELLY_BEAN}, this function 650ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * would not correctly retrieve the final configuration density when 651ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the resource ID passed here is an alias to another Drawable resource. 652ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * This means that if the density configuration of the alias resource 653ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * is different than the actual resource, the density of the returned 6542102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Drawable would be incorrect, resulting in bad scaling. To work 655ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * around this, you can instead retrieve the Drawable through 656ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link TypedArray#getDrawable TypedArray.getDrawable}. Use 657ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link android.content.Context#obtainStyledAttributes(int[]) 658ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Context.obtainStyledAttributes} with 659ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * an array containing the resource ID of interest to create the TypedArray.</p> 660ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 661ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 6622102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 663ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 664ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 665ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 666ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 667ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Drawable An object that can be used to draw this resource. 668ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 669ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public Drawable getDrawable(int id) throws NotFoundException { 6702102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa TypedValue value; 671ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 672ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = mTmpValue; 673ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 674ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = new TypedValue(); 675ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else { 676ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = null; 677ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 678ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 679ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 680ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Drawable res = loadDrawable(value, id); 681ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 682ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mTmpValue == null) { 683ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value; 684ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 685ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 686ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 687ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 688ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 689ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 690ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a drawable object associated with a particular resource ID for the 6912102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * given screen density in DPI. This will set the drawable's density to be 692ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the device's density multiplied by the ratio of actual drawable density 693ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * to requested density. This allows the drawable to be scaled up to the 694ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * correct size if needed. Various types of objects will be returned 695ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * depending on the underlying resource -- for example, a solid color, PNG 696ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * image, scalable image, etc. The Drawable API hides these implementation 697ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * details. 698ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 6992102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt tool. 700ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * This integer encodes the package, type, and resource entry. 701ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * The value 0 is an invalid identifier. 702ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param density the desired screen density indicated by the resource as 703ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * found in {@link DisplayMetrics}. 704ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does 705ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * not exist. 706ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Drawable An object that can be used to draw this resource. 7072102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 708ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public Drawable getDrawableForDensity(int id, int density) throws NotFoundException { 709ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value; 710ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 711ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = mTmpValue; 712ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 713ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = new TypedValue(); 714ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else { 715ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = null; 716ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 717ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValueForDensity(id, density, value, true); 718ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 719ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /* 720ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Pretend the requested density is actually the display density. If 721ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the drawable returned is not the requested density, then force it 722ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * to be scaled later by dividing its density by the ratio of 723ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * requested density to actual device density. Drawables that have 7242102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * undefined density or no density don't need to be handled here. 725ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 726ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.density > 0 && value.density != TypedValue.DENSITY_NONE) { 727ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.density == density) { 728ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.density = mMetrics.densityDpi; 729ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else { 730ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.density = (value.density * mMetrics.densityDpi) / density; 731ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 7322102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 733ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 734ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 735ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Drawable res = loadDrawable(value, id); 736ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 737ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mTmpValue == null) { 738ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value; 7392102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 740ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 741ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 742ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 743ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 744ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 745ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a movie object associated with the particular resource ID. 7462102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 747ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 748ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 749ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 750ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 751ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 752ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public Movie getMovie(int id) throws NotFoundException { 753ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa InputStream is = openRawResource(id); 754ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Movie movie = Movie.decodeStream(is); 755ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa try { 756ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa is.close(); 757ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 758ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa catch (java.io.IOException e) { 759ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa // don't care, since the return value is valid 760ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 761ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return movie; 762ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 763ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 764ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 765ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a color integer associated with a particular resource ID. 766ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * If the resource holds a complex 767ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link android.content.res.ColorStateList}, then the default color from 768ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the set is returned. 769ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 770ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 771ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 772ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 7732102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 774ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 775ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 776ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Returns a single color value in the form 0xAARRGGBB. 777ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 778ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public int getColor(int id) throws NotFoundException { 779ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value; 780ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 7812102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value = mTmpValue; 782ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 783ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = new TypedValue(); 784ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 785ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 786ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type >= TypedValue.TYPE_FIRST_INT 787ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa && value.type <= TypedValue.TYPE_LAST_INT) { 788ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value; 78952617bbff8607cdc208ba107ec111bd1471433cbTsuwei Chen return value.data; 790ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else if (value.type != TypedValue.TYPE_STRING) { 791ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 792ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 793ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(value.type) + " is not valid"); 794ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 795ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = null; 79652617bbff8607cdc208ba107ec111bd1471433cbTsuwei Chen } 7972102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa ColorStateList csl = loadColorStateList(value, id); 798ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 799ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mTmpValue == null) { 800ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value; 801ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 802ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 803ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return csl.getDefaultColor(); 804ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 8052102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 80652617bbff8607cdc208ba107ec111bd1471433cbTsuwei Chen /** 807ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a color state list associated with a particular resource ID. The 808ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resource may contain either a single raw color value, or a complex 809ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link android.content.res.ColorStateList} holding multiple possible colors. 8102102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 811ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier of a {@link ColorStateList}, 8122102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * as generated by the aapt tool. This integer encodes the package, type, and resource 8132102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * entry. The value 0 is an invalid identifier. 814ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 815ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 816ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 8172102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return Returns a ColorStateList object containing either a single 8182102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * solid color or multiple colors that can be selected based on a state. 819ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 8202102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public ColorStateList getColorStateList(int id) throws NotFoundException { 821ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value; 8222102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa synchronized (mAccessLock) { 8232102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value = mTmpValue; 824ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 825ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = new TypedValue(); 826ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else { 8272102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa mTmpValue = null; 828ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 8292102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa getValue(id, value, true); 8302102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 8312102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa ColorStateList res = loadColorStateList(value, id); 832ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 833ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mTmpValue == null) { 834ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value; 8352102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 836ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 8372102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return res; 8382102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 8392102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 840ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 841ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a boolean associated with a particular resource ID. This can be 842ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * used with any integral resource value, and will return true if it is 843ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * non-zero. 844ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 845ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 8462102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 847ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 848ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 849ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 850ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 851ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Returns the boolean value contained in the resource. 852ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 853ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public boolean getBoolean(int id) throws NotFoundException { 854ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 855ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value = mTmpValue; 856ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 857ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value = new TypedValue(); 858ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 859ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 860ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type >= TypedValue.TYPE_FIRST_INT 861ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa && value.type <= TypedValue.TYPE_LAST_INT) { 862ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return value.data != 0; 863ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 864ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 865ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 8662102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa + Integer.toHexString(value.type) + " is not valid"); 867ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 868ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 869ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 870ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 871ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return an integer associated with a particular resource ID. 872ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 873ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 8742102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * tool. This integer encodes the package, type, and resource 875ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 876ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 877ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 878ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 879ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Returns the integer value contained in the resource. 880ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 881ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public int getInteger(int id) throws NotFoundException { 8822102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa synchronized (mAccessLock) { 883ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value = mTmpValue; 884ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 885ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value = new TypedValue(); 886ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 887ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 888ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value.type >= TypedValue.TYPE_FIRST_INT 889ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa && value.type <= TypedValue.TYPE_LAST_INT) { 890ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return value.data; 891ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 892ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException( 893ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 894ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(value.type) + " is not valid"); 895ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 896ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 897ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 898ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 8992102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return an XmlResourceParser through which you can read a view layout 900ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * description for the given resource ID. This parser has limited 901ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * functionality -- in particular, you can't change its input, and only 902ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the high-level events are available. 903ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 904ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>This function is really a simple wrapper for calling 905ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link #getXml} with a layout resource. 906ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 9072102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 908ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 909ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 910ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 911ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 912ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 913ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return A new parser object through which you can read 9142102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * the XML data. 915ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 916ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getXml 917ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 918ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public XmlResourceParser getLayout(int id) throws NotFoundException { 919ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return loadXmlResourceParser(id, "layout"); 920ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 9212102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 922ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 923ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return an XmlResourceParser through which you can read an animation 924ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * description for the given resource ID. This parser has limited 925ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * functionality -- in particular, you can't change its input, and only 926ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the high-level events are available. 927ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 928ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>This function is really a simple wrapper for calling 929ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * {@link #getXml} with an animation resource. 930ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 931ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 932ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 933ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 934ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 935ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 936ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 937ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return A new parser object through which you can read 938ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the XML data. 939ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 940ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getXml 941ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 942ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public XmlResourceParser getAnimation(int id) throws NotFoundException { 943ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return loadXmlResourceParser(id, "anim"); 944ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 945ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 9462102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 947ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return an XmlResourceParser through which you can read a generic XML 9482102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * resource for the given resource ID. 949ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 950ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>The XmlPullParser implementation returned here has some limited 951ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * functionality. In particular, you can't change its input, and only 952ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * high-level parsing events are available (since the document was 953ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * pre-parsed for you at build time, which involved merging text and 954ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * stripping comments). 955ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 9562102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The desired resource identifier, as generated by the aapt 957ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 958ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 959ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 960ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 961ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 962ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return A new parser object through which you can read 963ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the XML data. 964ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 965ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see android.util.AttributeSet 966ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 967ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public XmlResourceParser getXml(int id) throws NotFoundException { 968ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return loadXmlResourceParser(id, "xml"); 969ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 970ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 971ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 9722102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Open a data stream for reading a raw resource. This can only be used 973ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * with resources whose value is the name of an asset files -- that is, it can be 974ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * used to open drawable, sound, and raw resources; it will fail on string 975ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * and color resources. 976ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 977ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The resource identifier to open, as generated by the appt 978ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. 979ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 9802102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return InputStream Access to the resource data. 981ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 982ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 983ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 984ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 985ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public InputStream openRawResource(int id) throws NotFoundException { 986ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value; 987ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 9882102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value = mTmpValue; 989ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 990ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = new TypedValue(); 991ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else { 992ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = null; 993ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 994ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 995ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa InputStream res = openRawResource(id, value); 996ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 997ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mTmpValue == null) { 998ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = value; 999ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1000ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1001ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return res; 1002ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1003ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1004ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 1005ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Open a data stream for reading a raw resource. This can only be used 10062102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * with resources whose value is the name of an asset file -- that is, it can be 1007ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * used to open drawable, sound, and raw resources; it will fail on string 1008ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * and color resources. 1009ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1010ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The resource identifier to open, as generated by the appt tool. 1011ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param value The TypedValue object to hold the resource information. 1012ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1013ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return InputStream Access to the resource data. 10142102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1015ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1016ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 1017ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public InputStream openRawResource(int id, TypedValue value) throws NotFoundException { 1018ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 1019ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1020ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa try { 1021ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return mAssets.openNonAsset(value.assetCookie, value.string.toString(), 10222102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa AssetManager.ACCESS_STREAMING); 1023ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } catch (Exception e) { 1024ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa NotFoundException rnf = new NotFoundException("File " + value.string.toString() + 1025ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa " from drawable resource ID #0x" + Integer.toHexString(id)); 1026ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa rnf.initCause(e); 1027ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw rnf; 1028ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1029ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1030ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1031ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 1032ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Open a file descriptor for reading a raw resource. This can only be used 1033ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * with resources whose value is the name of an asset files -- that is, it can be 1034ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * used to open drawable, sound, and raw resources; it will fail on string 1035ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * and color resources. 1036ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1037ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>This function only works for resources that are stored in the package 1038ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * as uncompressed data, which typically includes things like mp3 files 1039ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * and png images. 1040ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 10412102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param id The resource identifier to open, as generated by the appt 1042ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. 1043ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1044ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return AssetFileDescriptor A new file descriptor you can use to read 1045ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the resource. This includes the file descriptor itself, as well as the 1046ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * offset and length of data where the resource appears in the file. A 1047ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * null is returned if the file exists but is compressed. 1048ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 10492102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1050ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1051ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 1052ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException { 1053ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedValue value; 1054ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 1055ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value = mTmpValue; 1056ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (value == null) { 10572102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value = new TypedValue(); 1058ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } else { 1059ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mTmpValue = null; 1060ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1061ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, value, true); 1062ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1063ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa try { 1064ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return mAssets.openNonAssetFd( 1065ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.assetCookie, value.string.toString()); 1066ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } catch (Exception e) { 1067ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa NotFoundException rnf = new NotFoundException( 1068ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa "File " + value.string.toString() 1069ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + " from drawable resource ID #0x" 1070ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 1071ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa rnf.initCause(e); 1072ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw rnf; 1073ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } finally { 1074ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mAccessLock) { 1075ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mTmpValue == null) { 10762102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa mTmpValue = value; 1077ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1078ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1079ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1080ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1081ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1082ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 1083ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return the raw data associated with a particular resource ID. 10842102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1085ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id The desired resource identifier, as generated by the aapt 1086ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * tool. This integer encodes the package, type, and resource 1087ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * entry. The value 0 is an invalid identifier. 1088ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param outValue Object in which to place the resource data. 1089ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param resolveRefs If true, a resource that is a reference to another 1090ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resource will be followed so that you receive the 1091ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * actual final resource data. If false, the TypedValue 10922102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * will be filled in with the reference itself. 1093ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1094ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1095ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1096ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 1097ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public void getValue(int id, TypedValue outValue, boolean resolveRefs) 1098ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throws NotFoundException { 1099ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs); 1100ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (found) { 1101ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return; 1102ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1103ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("Resource ID #0x" 1104ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + Integer.toHexString(id)); 1105ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1106ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1107ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 1108ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Get the raw value associated with a resource with associated density. 1109ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1110ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param id resource identifier 11112102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param density density in DPI 1112ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param resolveRefs If true, a resource that is a reference to another 1113ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resource will be followed so that you receive the actual final 1114ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resource data. If false, the TypedValue will be filled in with 1115ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the reference itself. 1116ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does 1117ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * not exist. 1118ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #getValue(String, TypedValue, boolean) 11192102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 1120ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public void getValueForDensity(int id, int density, TypedValue outValue, boolean resolveRefs) 1121ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throws NotFoundException { 1122ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa boolean found = mAssets.getResourceValue(id, density, outValue, resolveRefs); 1123ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (found) { 1124ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return; 1125ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1126ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)); 1127ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1128ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 11292102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 1130ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return the raw data associated with a particular resource ID. 1131ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * See getIdentifier() for information on how names are mapped to resource 1132ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * IDs, and getString(int) for information on how string resources are 1133ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * retrieved. 1134ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1135ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>Note: use of this function is discouraged. It is much more 1136ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * efficient to retrieve resources by identifier than by name. 1137ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1138ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param name The name of the desired resource. This is passed to 1139ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * getIdentifier() with a default type of "string". 1140ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param outValue Object in which to place the resource data. 1141ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param resolveRefs If true, a resource that is a reference to another 1142ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resource will be followed so that you receive the 1143ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * actual final resource data. If false, the TypedValue 1144ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * will be filled in with the reference itself. 11452102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1146ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 11472102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 11482102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 1149ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public void getValue(String name, TypedValue outValue, boolean resolveRefs) 115081cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa throws NotFoundException { 1151ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int id = getIdentifier(name, "string", null); 1152ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (id != 0) { 1153ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa getValue(id, outValue, resolveRefs); 11542102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa return; 1155ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1156ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa throw new NotFoundException("String resource name " + name); 1157ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1158ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1159ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 1160ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * This class holds the current attribute values for a particular theme. 1161ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * In other words, a Theme is a set of values for resource attributes; 1162ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * these are used in conjunction with {@link TypedArray} 1163ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * to resolve the final value for an attribute. 1164ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 11652102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <p>The Theme's attributes come into play in two ways: (1) a styled 116652617bbff8607cdc208ba107ec111bd1471433cbTsuwei Chen * attribute can explicit reference a value in the theme through the 11672102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * "?themeAttribute" syntax; (2) if no value has been defined for a 1168ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * particular styled attribute, as a last resort we will try to find that 1169ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * attribute's value in the Theme. 11702102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1171ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>You will normally use the {@link #obtainStyledAttributes} APIs to 1172ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * retrieve XML attributes with style and theme information applied. 1173ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 1174ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public final class Theme { 1175ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 1176ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Place new attribute values into the theme. The style resource 1177ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * specified by <var>resid</var> will be retrieved from this Theme's 1178ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * resources, its values placed into the Theme object. 1179ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1180ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>The semantics of this function depends on the <var>force</var> 1181ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * argument: If false, only values that are not already defined in 1182ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the theme will be copied from the system resource; otherwise, if 1183ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * any of the style's attributes are already defined in the theme, the 1184ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * current values in the theme will be overwritten. 1185ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1186ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param resid The resource ID of a style resource from which to 1187ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * obtain attribute values. 11882102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param force If true, values in the style resource will always be 1189ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * used in the theme; otherwise, they will only be used 11902102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * if not already defined in the theme. 11912102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 1192ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public void applyStyle(int resid, boolean force) { 119381cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa AssetManager.applyThemeStyle(mTheme, resid, force); 1194ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1195ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1196ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 11972102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Set this theme to hold the same contents as the theme 1198ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <var>other</var>. If both of these themes are from the same 1199ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Resources object, they will be identical after this function 1200ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * returns. If they are from different Resources, only the resources 1201ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * they have in common will be set in this theme. 1202ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1203ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param other The existing Theme to copy from. 1204ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 1205ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public void setTo(Theme other) { 1206ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa AssetManager.copyTheme(mTheme, other.mTheme); 1207ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 12082102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1209ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa /** 12102102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * Return a TypedArray holding the values defined by 1211ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <var>Theme</var> which are listed in <var>attrs</var>. 1212ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 12132102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done 1214ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * with the array. 1215ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1216ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param attrs The desired attributes. 1217ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1218ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1219ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1220ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Returns a TypedArray holding an array of the attribute values. 1221ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} 1222ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * when done with it. 1223ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1224ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see Resources#obtainAttributes 1225ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #obtainStyledAttributes(int, int[]) 1226ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #obtainStyledAttributes(AttributeSet, int[], int, int) 1227ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 1228ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public TypedArray obtainStyledAttributes(int[] attrs) { 1229ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int len = attrs.length; 1230ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa TypedArray array = getCachedStyledAttributes(len); 1231ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa array.mRsrcs = attrs; 1232ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa AssetManager.applyStyle(mTheme, 0, 0, 0, attrs, 1233ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa array.mData, array.mIndices); 1234ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return array; 12352102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 12362102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 12372102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 1238ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a TypedArray holding the values defined by the style 123981cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * resource <var>resid</var> which are listed in <var>attrs</var>. 124081cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * 124181cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done 124281cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * with the array. 124381cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * 124481cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa * @param resid The desired style resource. 1245ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param attrs The desired attributes in the style. 1246ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1247ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1248ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1249ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @return Returns a TypedArray holding an array of the attribute values. 1250ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} 1251ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * when done with it. 1252ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1253ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see Resources#obtainAttributes 1254ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #obtainStyledAttributes(int[]) 1255ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #obtainStyledAttributes(AttributeSet, int[], int, int) 12562102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa */ 12572102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public TypedArray obtainStyledAttributes(int resid, int[] attrs) 12582102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa throws NotFoundException { 12592102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int len = attrs.length; 12602102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa TypedArray array = getCachedStyledAttributes(len); 1261ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa array.mRsrcs = attrs; 1262ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1263ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa AssetManager.applyStyle(mTheme, 0, resid, 0, attrs, 1264ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa array.mData, array.mIndices); 1265ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (false) { 1266ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int[] data = array.mData; 1267ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1268ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa System.out.println("**********************************************************"); 1269ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa System.out.println("**********************************************************"); 12702102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa System.out.println("**********************************************************"); 1271ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa System.out.println("Attributes:"); 12722102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa String s = " Attrs:"; 1273ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int i; 1274ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa for (i=0; i<attrs.length; i++) { 1275ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa s = s + " 0x" + Integer.toHexString(attrs[i]); 1276ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 12772102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa System.out.println(s); 1278ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa s = " Found:"; 12792102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa TypedValue value = new TypedValue(); 1280ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa for (i=0; i<attrs.length; i++) { 1281ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa int d = i*AssetManager.STYLE_NUM_ENTRIES; 1282ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.type = data[d+AssetManager.STYLE_TYPE]; 1283ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.data = data[d+AssetManager.STYLE_DATA]; 12842102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE]; 1285ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID]; 1286ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa s = s + " 0x" + Integer.toHexString(attrs[i]) 1287ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa + "=" + value; 1288ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 12892102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa System.out.println(s); 1290ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1291ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return array; 1292ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1293ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 12942102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa /** 1295ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Return a TypedArray holding the attribute values in 12962102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <var>set</var> 1297ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * that are listed in <var>attrs</var>. In addition, if the given 1298ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * AttributeSet specifies a style class (through the "style" attribute), 1299ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * that style will be applied on top of the base attributes it defines. 1300ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1301ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done 1302ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * with the array. 13032102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1304ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>When determining the final value of a particular attribute, there 1305ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * are four inputs that come into play:</p> 1306ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 13072102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <ol> 13082102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <li> Any attribute values in the given AttributeSet. 1309ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <li> The style resource specified in the AttributeSet (named 1310ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * "style"). 1311ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <li> The default style specified by <var>defStyleAttr</var> and 1312ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <var>defStyleRes</var> 13132102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * <li> The base values in this theme. 1314ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * </ol> 13152102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1316ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <p>Each of these inputs is considered in-order, with the first listed 1317ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * taking precedence over the following ones. In other words, if in the 1318ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * AttributeSet you have supplied <code><Button 1319ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * textColor="#ff000000"></code>, then the button's text will 1320ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * <em>always</em> be black, regardless of what is specified in any of 1321ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * the styles. 13222102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * 1323ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param set The base set of attribute values. May be null. 1324ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param attrs The desired attributes to be retrieved. 1325ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @param defStyleAttr An attribute in the current theme that contains a 1326ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * reference to a style resource that supplies 13272102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * defaults values for the TypedArray. Can be 1328ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 0 to not look for defaults. 13292102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @param defStyleRes A resource identifier of a style resource that 1330ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * supplies default values for the TypedArray, 1331ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * used only if defStyleAttr is 0 or can not be found 1332ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * in the theme. Can be 0 to not look for defaults. 1333ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 13342102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * @return Returns a TypedArray holding an array of the attribute values. 1335ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} 13362102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa * when done with it. 1337ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 1338ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see Resources#obtainAttributes 1339ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #obtainStyledAttributes(int[]) 1340ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * @see #obtainStyledAttributes(int, int[]) 1341ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 13422102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa public TypedArray obtainStyledAttributes(AttributeSet set, 13432102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int[] attrs, int defStyleAttr, int defStyleRes) { 13442102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int len = attrs.length; 13452102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa TypedArray array = getCachedStyledAttributes(len); 13462102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 13472102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // XXX note that for now we only work with compiled XML files. 13482102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // To support generic XML files we will need to manually parse 134981cabb8a7fb5b61f16bf49c2757ccb51bc88e708destradaa // out the attributes from the XML file (applying type information 13502102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa // contained in the resources and such). 13512102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa XmlBlock.Parser parser = (XmlBlock.Parser)set; 13522102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa AssetManager.applyStyle( 13532102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa mTheme, defStyleAttr, defStyleRes, 13542102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa parser != null ? parser.mParseState : 0, attrs, 13552102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa array.mData, array.mIndices); 13562102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 13572102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa array.mRsrcs = attrs; 13582102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa array.mXml = parser; 13592102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 13602102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (false) { 13612102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int[] data = array.mData; 13622102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 13632102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa System.out.println("Attributes:"); 13642102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa String s = " Attrs:"; 13652102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int i; 13662102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa for (i=0; i<set.getAttributeCount(); i++) { 13672102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa s = s + " " + set.getAttributeName(i); 13682102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int id = set.getAttributeNameResource(i); 13692102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa if (id != 0) { 13702102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa s = s + "(0x" + Integer.toHexString(id) + ")"; 13712102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 13722102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa s = s + "=" + set.getAttributeValue(i); 13732102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 13742102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa System.out.println(s); 13752102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa s = " Found:"; 13762102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa TypedValue value = new TypedValue(); 13772102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa for (i=0; i<attrs.length; i++) { 13782102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa int d = i*AssetManager.STYLE_NUM_ENTRIES; 13792102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value.type = data[d+AssetManager.STYLE_TYPE]; 13802102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value.data = data[d+AssetManager.STYLE_DATA]; 13812102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE]; 13822102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID]; 13832102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa s = s + " 0x" + Integer.toHexString(attrs[i]) 13842102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa + "=" + value; 13852102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 13862102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa System.out.println(s); 13872102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa } 13882102dd725540bcf51bf324a2775fbcffe45dd32fdestradaa 1389ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return array; 1390 } 1391 1392 /** 1393 * Retrieve the value of an attribute in the Theme. The contents of 1394 * <var>outValue</var> are ultimately filled in by 1395 * {@link Resources#getValue}. 1396 * 1397 * @param resid The resource identifier of the desired theme 1398 * attribute. 1399 * @param outValue Filled in with the ultimate resource value supplied 1400 * by the attribute. 1401 * @param resolveRefs If true, resource references will be walked; if 1402 * false, <var>outValue</var> may be a 1403 * TYPE_REFERENCE. In either case, it will never 1404 * be a TYPE_ATTRIBUTE. 1405 * 1406 * @return boolean Returns true if the attribute was found and 1407 * <var>outValue</var> is valid, else false. 1408 */ 1409 public boolean resolveAttribute(int resid, TypedValue outValue, 1410 boolean resolveRefs) { 1411 boolean got = mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs); 1412 if (false) { 1413 System.out.println( 1414 "resolveAttribute #" + Integer.toHexString(resid) 1415 + " got=" + got + ", type=0x" + Integer.toHexString(outValue.type) 1416 + ", data=0x" + Integer.toHexString(outValue.data)); 1417 } 1418 return got; 1419 } 1420 1421 /** 1422 * Print contents of this theme out to the log. For debugging only. 1423 * 1424 * @param priority The log priority to use. 1425 * @param tag The log tag to use. 1426 * @param prefix Text to prefix each line printed. 1427 */ 1428 public void dump(int priority, String tag, String prefix) { 1429 AssetManager.dumpTheme(mTheme, priority, tag, prefix); 1430 } 1431 1432 protected void finalize() throws Throwable { 1433 super.finalize(); 1434 mAssets.releaseTheme(mTheme); 1435 } 1436 1437 /*package*/ Theme() { 1438 mAssets = Resources.this.mAssets; 1439 mTheme = mAssets.createTheme(); 1440 } 1441 1442 private final AssetManager mAssets; 1443 private final int mTheme; 1444 } 1445 1446 /** 1447 * Generate a new Theme object for this set of Resources. It initially 1448 * starts out empty. 1449 * 1450 * @return Theme The newly created Theme container. 1451 */ 1452 public final Theme newTheme() { 1453 return new Theme(); 1454 } 1455 1456 /** 1457 * Retrieve a set of basic attribute values from an AttributeSet, not 1458 * performing styling of them using a theme and/or style resources. 1459 * 1460 * @param set The current attribute values to retrieve. 1461 * @param attrs The specific attributes to be retrieved. 1462 * @return Returns a TypedArray holding an array of the attribute values. 1463 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} 1464 * when done with it. 1465 * 1466 * @see Theme#obtainStyledAttributes(AttributeSet, int[], int, int) 1467 */ 1468 public TypedArray obtainAttributes(AttributeSet set, int[] attrs) { 1469 int len = attrs.length; 1470 TypedArray array = getCachedStyledAttributes(len); 1471 1472 // XXX note that for now we only work with compiled XML files. 1473 // To support generic XML files we will need to manually parse 1474 // out the attributes from the XML file (applying type information 1475 // contained in the resources and such). 1476 XmlBlock.Parser parser = (XmlBlock.Parser)set; 1477 mAssets.retrieveAttributes(parser.mParseState, attrs, 1478 array.mData, array.mIndices); 1479 1480 array.mRsrcs = attrs; 1481 array.mXml = parser; 1482 1483 return array; 1484 } 1485 1486 /** 1487 * Store the newly updated configuration. 1488 */ 1489 public void updateConfiguration(Configuration config, 1490 DisplayMetrics metrics) { 1491 updateConfiguration(config, metrics, null); 1492 } 1493 1494 /** 1495 * @hide 1496 */ 1497 public void updateConfiguration(Configuration config, 1498 DisplayMetrics metrics, CompatibilityInfo compat) { 1499 synchronized (mAccessLock) { 1500 if (false) { 1501 Slog.i(TAG, "**** Updating config of " + this + ": old config is " 1502 + mConfiguration + " old compat is " + mCompatibilityInfo); 1503 Slog.i(TAG, "**** Updating config of " + this + ": new config is " 1504 + config + " new compat is " + compat); 1505 } 1506 if (compat != null) { 1507 mCompatibilityInfo = compat; 1508 } 1509 if (metrics != null) { 1510 mMetrics.setTo(metrics); 1511 } 1512 // NOTE: We should re-arrange this code to create a Display 1513 // with the CompatibilityInfo that is used everywhere we deal 1514 // with the display in relation to this app, rather than 1515 // doing the conversion here. This impl should be okay because 1516 // we make sure to return a compatible display in the places 1517 // where there are public APIs to retrieve the display... but 1518 // it would be cleaner and more maintainble to just be 1519 // consistently dealing with a compatible display everywhere in 1520 // the framework. 1521 if (mCompatibilityInfo != null) { 1522 mCompatibilityInfo.applyToDisplayMetrics(mMetrics); 1523 } 1524 int configChanges = 0xfffffff; 1525 if (config != null) { 1526 mTmpConfig.setTo(config); 1527 int density = config.densityDpi; 1528 if (density == Configuration.DENSITY_DPI_UNDEFINED) { 1529 density = mMetrics.noncompatDensityDpi; 1530 } 1531 if (mCompatibilityInfo != null) { 1532 mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); 1533 } 1534 if (mTmpConfig.locale == null) { 1535 mTmpConfig.locale = Locale.getDefault(); 1536 mTmpConfig.setLayoutDirection(mTmpConfig.locale); 1537 } 1538 configChanges = mConfiguration.updateFrom(mTmpConfig); 1539 configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); 1540 } 1541 if (mConfiguration.locale == null) { 1542 mConfiguration.locale = Locale.getDefault(); 1543 mConfiguration.setLayoutDirection(mConfiguration.locale); 1544 } 1545 if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) { 1546 mMetrics.densityDpi = mConfiguration.densityDpi; 1547 mMetrics.density = mConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; 1548 } 1549 mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; 1550 1551 String locale = null; 1552 if (mConfiguration.locale != null) { 1553 locale = mConfiguration.locale.getLanguage(); 1554 if (mConfiguration.locale.getCountry() != null) { 1555 locale += "-" + mConfiguration.locale.getCountry(); 1556 } 1557 } 1558 int width, height; 1559 if (mMetrics.widthPixels >= mMetrics.heightPixels) { 1560 width = mMetrics.widthPixels; 1561 height = mMetrics.heightPixels; 1562 } else { 1563 //noinspection SuspiciousNameCombination 1564 width = mMetrics.heightPixels; 1565 //noinspection SuspiciousNameCombination 1566 height = mMetrics.widthPixels; 1567 } 1568 int keyboardHidden = mConfiguration.keyboardHidden; 1569 if (keyboardHidden == Configuration.KEYBOARDHIDDEN_NO 1570 && mConfiguration.hardKeyboardHidden 1571 == Configuration.HARDKEYBOARDHIDDEN_YES) { 1572 keyboardHidden = Configuration.KEYBOARDHIDDEN_SOFT; 1573 } 1574 mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc, 1575 locale, mConfiguration.orientation, 1576 mConfiguration.touchscreen, 1577 mConfiguration.densityDpi, mConfiguration.keyboard, 1578 keyboardHidden, mConfiguration.navigation, width, height, 1579 mConfiguration.smallestScreenWidthDp, 1580 mConfiguration.screenWidthDp, mConfiguration.screenHeightDp, 1581 mConfiguration.screenLayout, mConfiguration.uiMode, 1582 Build.VERSION.RESOURCES_SDK_INT); 1583 1584 if (DEBUG_CONFIG) { 1585 Slog.i(TAG, "**** Updating config of " + this + ": final config is " + mConfiguration 1586 + " final compat is " + mCompatibilityInfo); 1587 } 1588 1589 clearDrawableCacheLocked(mDrawableCache, configChanges); 1590 clearDrawableCacheLocked(mColorDrawableCache, configChanges); 1591 1592 mColorStateListCache.clear(); 1593 1594 flushLayoutCache(); 1595 } 1596 synchronized (sSync) { 1597 if (mPluralRule != null) { 1598 mPluralRule = NativePluralRules.forLocale(config.locale); 1599 } 1600 } 1601 } 1602 1603 private void clearDrawableCacheLocked( 1604 LongSparseArray<WeakReference<ConstantState>> cache, 1605 int configChanges) { 1606 int N = cache.size(); 1607 if (DEBUG_CONFIG) { 1608 Log.d(TAG, "Cleaning up drawables config changes: 0x" 1609 + Integer.toHexString(configChanges)); 1610 } 1611 for (int i=0; i<N; i++) { 1612 WeakReference<Drawable.ConstantState> ref = cache.valueAt(i); 1613 if (ref != null) { 1614 Drawable.ConstantState cs = ref.get(); 1615 if (cs != null) { 1616 if (Configuration.needNewResources( 1617 configChanges, cs.getChangingConfigurations())) { 1618 if (DEBUG_CONFIG) { 1619 Log.d(TAG, "FLUSHING #0x" 1620 + Long.toHexString(mDrawableCache.keyAt(i)) 1621 + " / " + cs + " with changes: 0x" 1622 + Integer.toHexString(cs.getChangingConfigurations())); 1623 } 1624 cache.setValueAt(i, null); 1625 } else if (DEBUG_CONFIG) { 1626 Log.d(TAG, "(Keeping #0x" 1627 + Long.toHexString(cache.keyAt(i)) 1628 + " / " + cs + " with changes: 0x" 1629 + Integer.toHexString(cs.getChangingConfigurations()) 1630 + ")"); 1631 } 1632 } 1633 } 1634 } 1635 } 1636 1637 /** 1638 * Update the system resources configuration if they have previously 1639 * been initialized. 1640 * 1641 * @hide 1642 */ 1643 public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics, 1644 CompatibilityInfo compat) { 1645 if (mSystem != null) { 1646 mSystem.updateConfiguration(config, metrics, compat); 1647 //Log.i(TAG, "Updated system resources " + mSystem 1648 // + ": " + mSystem.getConfiguration()); 1649 } 1650 } 1651 1652 /** 1653 * @hide 1654 */ 1655 public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics) { 1656 updateSystemConfiguration(config, metrics, null); 1657 } 1658 1659 /** 1660 * Return the current display metrics that are in effect for this resource 1661 * object. The returned object should be treated as read-only. 1662 * 1663 * @return The resource's current display metrics. 1664 */ 1665 public DisplayMetrics getDisplayMetrics() { 1666 if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels 1667 + "x" + mMetrics.heightPixels + " " + mMetrics.density); 1668 return mMetrics; 1669 } 1670 1671 /** 1672 * Return the current configuration that is in effect for this resource 1673 * object. The returned object should be treated as read-only. 1674 * 1675 * @return The resource's current configuration. 1676 */ 1677 public Configuration getConfiguration() { 1678 return mConfiguration; 1679 } 1680 1681 /** 1682 * Return the compatibility mode information for the application. 1683 * The returned object should be treated as read-only. 1684 * 1685 * @return compatibility info. 1686 * @hide 1687 */ 1688 public CompatibilityInfo getCompatibilityInfo() { 1689 return mCompatibilityInfo != null ? mCompatibilityInfo 1690 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; 1691 } 1692 1693 /** 1694 * This is just for testing. 1695 * @hide 1696 */ 1697 public void setCompatibilityInfo(CompatibilityInfo ci) { 1698 mCompatibilityInfo = ci; 1699 updateConfiguration(mConfiguration, mMetrics); 1700 } 1701 1702 /** 1703 * Return a resource identifier for the given resource name. A fully 1704 * qualified resource name is of the form "package:type/entry". The first 1705 * two components (package and type) are optional if defType and 1706 * defPackage, respectively, are specified here. 1707 * 1708 * <p>Note: use of this function is discouraged. It is much more 1709 * efficient to retrieve resources by identifier than by name. 1710 * 1711 * @param name The name of the desired resource. 1712 * @param defType Optional default resource type to find, if "type/" is 1713 * not included in the name. Can be null to require an 1714 * explicit type. 1715 * @param defPackage Optional default package to find, if "package:" is 1716 * not included in the name. Can be null to require an 1717 * explicit package. 1718 * 1719 * @return int The associated resource identifier. Returns 0 if no such 1720 * resource was found. (0 is not a valid resource ID.) 1721 */ 1722 public int getIdentifier(String name, String defType, String defPackage) { 1723 if (name == null) { 1724 throw new NullPointerException("name is null"); 1725 } 1726 try { 1727 return Integer.parseInt(name); 1728 } catch (Exception e) { 1729 // Ignore 1730 } 1731 return mAssets.getResourceIdentifier(name, defType, defPackage); 1732 } 1733 1734 /** 1735 * Return the full name for a given resource identifier. This name is 1736 * a single string of the form "package:type/entry". 1737 * 1738 * @param resid The resource identifier whose name is to be retrieved. 1739 * 1740 * @return A string holding the name of the resource. 1741 * 1742 * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1743 * 1744 * @see #getResourcePackageName 1745 * @see #getResourceTypeName 1746 * @see #getResourceEntryName 1747 */ 1748 public String getResourceName(int resid) throws NotFoundException { 1749 String str = mAssets.getResourceName(resid); 1750 if (str != null) return str; 1751 throw new NotFoundException("Unable to find resource ID #0x" 1752 + Integer.toHexString(resid)); 1753 } 1754 1755 /** 1756 * Return the package name for a given resource identifier. 1757 * 1758 * @param resid The resource identifier whose package name is to be 1759 * retrieved. 1760 * 1761 * @return A string holding the package name of the resource. 1762 * 1763 * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1764 * 1765 * @see #getResourceName 1766 */ 1767 public String getResourcePackageName(int resid) throws NotFoundException { 1768 String str = mAssets.getResourcePackageName(resid); 1769 if (str != null) return str; 1770 throw new NotFoundException("Unable to find resource ID #0x" 1771 + Integer.toHexString(resid)); 1772 } 1773 1774 /** 1775 * Return the type name for a given resource identifier. 1776 * 1777 * @param resid The resource identifier whose type name is to be 1778 * retrieved. 1779 * 1780 * @return A string holding the type name of the resource. 1781 * 1782 * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1783 * 1784 * @see #getResourceName 1785 */ 1786 public String getResourceTypeName(int resid) throws NotFoundException { 1787 String str = mAssets.getResourceTypeName(resid); 1788 if (str != null) return str; 1789 throw new NotFoundException("Unable to find resource ID #0x" 1790 + Integer.toHexString(resid)); 1791 } 1792 1793 /** 1794 * Return the entry name for a given resource identifier. 1795 * 1796 * @param resid The resource identifier whose entry name is to be 1797 * retrieved. 1798 * 1799 * @return A string holding the entry name of the resource. 1800 * 1801 * @throws NotFoundException Throws NotFoundException if the given ID does not exist. 1802 * 1803 * @see #getResourceName 1804 */ 1805 public String getResourceEntryName(int resid) throws NotFoundException { 1806 String str = mAssets.getResourceEntryName(resid); 1807 if (str != null) return str; 1808 throw new NotFoundException("Unable to find resource ID #0x" 1809 + Integer.toHexString(resid)); 1810 } 1811 1812 /** 1813 * Parse a series of {@link android.R.styleable#Extra <extra>} tags from 1814 * an XML file. You call this when you are at the parent tag of the 1815 * extra tags, and it will return once all of the child tags have been parsed. 1816 * This will call {@link #parseBundleExtra} for each extra tag encountered. 1817 * 1818 * @param parser The parser from which to retrieve the extras. 1819 * @param outBundle A Bundle in which to place all parsed extras. 1820 * @throws XmlPullParserException 1821 * @throws IOException 1822 */ 1823 public void parseBundleExtras(XmlResourceParser parser, Bundle outBundle) 1824 throws XmlPullParserException, IOException { 1825 int outerDepth = parser.getDepth(); 1826 int type; 1827 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1828 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1829 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1830 continue; 1831 } 1832 1833 String nodeName = parser.getName(); 1834 if (nodeName.equals("extra")) { 1835 parseBundleExtra("extra", parser, outBundle); 1836 XmlUtils.skipCurrentTag(parser); 1837 1838 } else { 1839 XmlUtils.skipCurrentTag(parser); 1840 } 1841 } 1842 } 1843 1844 /** 1845 * Parse a name/value pair out of an XML tag holding that data. The 1846 * AttributeSet must be holding the data defined by 1847 * {@link android.R.styleable#Extra}. The following value types are supported: 1848 * <ul> 1849 * <li> {@link TypedValue#TYPE_STRING}: 1850 * {@link Bundle#putCharSequence Bundle.putCharSequence()} 1851 * <li> {@link TypedValue#TYPE_INT_BOOLEAN}: 1852 * {@link Bundle#putCharSequence Bundle.putBoolean()} 1853 * <li> {@link TypedValue#TYPE_FIRST_INT}-{@link TypedValue#TYPE_LAST_INT}: 1854 * {@link Bundle#putCharSequence Bundle.putBoolean()} 1855 * <li> {@link TypedValue#TYPE_FLOAT}: 1856 * {@link Bundle#putCharSequence Bundle.putFloat()} 1857 * </ul> 1858 * 1859 * @param tagName The name of the tag these attributes come from; this is 1860 * only used for reporting error messages. 1861 * @param attrs The attributes from which to retrieve the name/value pair. 1862 * @param outBundle The Bundle in which to place the parsed value. 1863 * @throws XmlPullParserException If the attributes are not valid. 1864 */ 1865 public void parseBundleExtra(String tagName, AttributeSet attrs, 1866 Bundle outBundle) throws XmlPullParserException { 1867 TypedArray sa = obtainAttributes(attrs, 1868 com.android.internal.R.styleable.Extra); 1869 1870 String name = sa.getString( 1871 com.android.internal.R.styleable.Extra_name); 1872 if (name == null) { 1873 sa.recycle(); 1874 throw new XmlPullParserException("<" + tagName 1875 + "> requires an android:name attribute at " 1876 + attrs.getPositionDescription()); 1877 } 1878 1879 TypedValue v = sa.peekValue( 1880 com.android.internal.R.styleable.Extra_value); 1881 if (v != null) { 1882 if (v.type == TypedValue.TYPE_STRING) { 1883 CharSequence cs = v.coerceToString(); 1884 outBundle.putCharSequence(name, cs); 1885 } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) { 1886 outBundle.putBoolean(name, v.data != 0); 1887 } else if (v.type >= TypedValue.TYPE_FIRST_INT 1888 && v.type <= TypedValue.TYPE_LAST_INT) { 1889 outBundle.putInt(name, v.data); 1890 } else if (v.type == TypedValue.TYPE_FLOAT) { 1891 outBundle.putFloat(name, v.getFloat()); 1892 } else { 1893 sa.recycle(); 1894 throw new XmlPullParserException("<" + tagName 1895 + "> only supports string, integer, float, color, and boolean at " 1896 + attrs.getPositionDescription()); 1897 } 1898 } else { 1899 sa.recycle(); 1900 throw new XmlPullParserException("<" + tagName 1901 + "> requires an android:value or android:resource attribute at " 1902 + attrs.getPositionDescription()); 1903 } 1904 1905 sa.recycle(); 1906 } 1907 1908 /** 1909 * Retrieve underlying AssetManager storage for these resources. 1910 */ 1911 public final AssetManager getAssets() { 1912 return mAssets; 1913 } 1914 1915 /** 1916 * Call this to remove all cached loaded layout resources from the 1917 * Resources object. Only intended for use with performance testing 1918 * tools. 1919 */ 1920 public final void flushLayoutCache() { 1921 synchronized (mCachedXmlBlockIds) { 1922 // First see if this block is in our cache. 1923 final int num = mCachedXmlBlockIds.length; 1924 for (int i=0; i<num; i++) { 1925 mCachedXmlBlockIds[i] = -0; 1926 XmlBlock oldBlock = mCachedXmlBlocks[i]; 1927 if (oldBlock != null) { 1928 oldBlock.close(); 1929 } 1930 mCachedXmlBlocks[i] = null; 1931 } 1932 } 1933 } 1934 1935 /** 1936 * Start preloading of resource data using this Resources object. Only 1937 * for use by the zygote process for loading common system resources. 1938 * {@hide} 1939 */ 1940 public final void startPreloading() { 1941 synchronized (sSync) { 1942 if (sPreloaded) { 1943 throw new IllegalStateException("Resources already preloaded"); 1944 } 1945 sPreloaded = true; 1946 mPreloading = true; 1947 sPreloadedDensity = DisplayMetrics.DENSITY_DEVICE; 1948 mConfiguration.densityDpi = sPreloadedDensity; 1949 updateConfiguration(null, null); 1950 } 1951 } 1952 1953 /** 1954 * Called by zygote when it is done preloading resources, to change back 1955 * to normal Resources operation. 1956 */ 1957 public final void finishPreloading() { 1958 if (mPreloading) { 1959 mPreloading = false; 1960 flushLayoutCache(); 1961 } 1962 } 1963 1964 private boolean verifyPreloadConfig(TypedValue value, String name) { 1965 if ((value.changingConfigurations&~(ActivityInfo.CONFIG_FONT_SCALE 1966 | ActivityInfo.CONFIG_DENSITY)) != 0) { 1967 String resName; 1968 try { 1969 resName = getResourceName(value.resourceId); 1970 } catch (NotFoundException e) { 1971 resName = "?"; 1972 } 1973 Log.w(TAG, "Preloaded " + name + " resource #0x" 1974 + Integer.toHexString(value.resourceId) 1975 + " (" + resName + ") that varies with configuration!!"); 1976 return false; 1977 } 1978 return true; 1979 } 1980 1981 /*package*/ Drawable loadDrawable(TypedValue value, int id) 1982 throws NotFoundException { 1983 1984 if (TRACE_FOR_PRELOAD) { 1985 // Log only framework resources 1986 if ((id >>> 24) == 0x1) { 1987 final String name = getResourceName(id); 1988 if (name != null) android.util.Log.d("PreloadDrawable", name); 1989 } 1990 } 1991 1992 boolean isColorDrawable = false; 1993 if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && 1994 value.type <= TypedValue.TYPE_LAST_COLOR_INT) { 1995 isColorDrawable = true; 1996 } 1997 final long key = isColorDrawable ? value.data : 1998 (((long) value.assetCookie) << 32) | value.data; 1999 2000 Drawable dr = getCachedDrawable(isColorDrawable ? mColorDrawableCache : mDrawableCache, key); 2001 2002 if (dr != null) { 2003 return dr; 2004 } 2005 2006 Drawable.ConstantState cs = isColorDrawable 2007 ? sPreloadedColorDrawables.get(key) 2008 : (sPreloadedDensity == mConfiguration.densityDpi 2009 ? sPreloadedDrawables.get(key) : null); 2010 if (cs != null) { 2011 dr = cs.newDrawable(this); 2012 } else { 2013 if (isColorDrawable) { 2014 dr = new ColorDrawable(value.data); 2015 } 2016 2017 if (dr == null) { 2018 if (value.string == null) { 2019 throw new NotFoundException( 2020 "Resource is not a Drawable (color or path): " + value); 2021 } 2022 2023 String file = value.string.toString(); 2024 2025 if (TRACE_FOR_MISS_PRELOAD) { 2026 // Log only framework resources 2027 if ((id >>> 24) == 0x1) { 2028 final String name = getResourceName(id); 2029 if (name != null) android.util.Log.d(TAG, "Loading framework drawable #" 2030 + Integer.toHexString(id) + ": " + name 2031 + " at " + file); 2032 } 2033 } 2034 2035 if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie " 2036 + value.assetCookie + ": " + file); 2037 2038 if (file.endsWith(".xml")) { 2039 try { 2040 XmlResourceParser rp = loadXmlResourceParser( 2041 file, id, value.assetCookie, "drawable"); 2042 dr = Drawable.createFromXml(this, rp); 2043 rp.close(); 2044 } catch (Exception e) { 2045 NotFoundException rnf = new NotFoundException( 2046 "File " + file + " from drawable resource ID #0x" 2047 + Integer.toHexString(id)); 2048 rnf.initCause(e); 2049 throw rnf; 2050 } 2051 2052 } else { 2053 try { 2054 InputStream is = mAssets.openNonAsset( 2055 value.assetCookie, file, AssetManager.ACCESS_STREAMING); 2056 // System.out.println("Opened file " + file + ": " + is); 2057 dr = Drawable.createFromResourceStream(this, value, is, 2058 file, null); 2059 is.close(); 2060 // System.out.println("Created stream: " + dr); 2061 } catch (Exception e) { 2062 NotFoundException rnf = new NotFoundException( 2063 "File " + file + " from drawable resource ID #0x" 2064 + Integer.toHexString(id)); 2065 rnf.initCause(e); 2066 throw rnf; 2067 } 2068 } 2069 } 2070 } 2071 2072 if (dr != null) { 2073 dr.setChangingConfigurations(value.changingConfigurations); 2074 cs = dr.getConstantState(); 2075 if (cs != null) { 2076 if (mPreloading) { 2077 if (verifyPreloadConfig(value, "drawable")) { 2078 if (isColorDrawable) { 2079 sPreloadedColorDrawables.put(key, cs); 2080 } else { 2081 sPreloadedDrawables.put(key, cs); 2082 } 2083 } 2084 } else { 2085 synchronized (mAccessLock) { 2086 //Log.i(TAG, "Saving cached drawable @ #" + 2087 // Integer.toHexString(key.intValue()) 2088 // + " in " + this + ": " + cs); 2089 if (isColorDrawable) { 2090 mColorDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs)); 2091 } else { 2092 mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs)); 2093 } 2094 } 2095 } 2096 } 2097 } 2098 2099 return dr; 2100 } 2101 2102 private Drawable getCachedDrawable( 2103 LongSparseArray<WeakReference<ConstantState>> drawableCache, 2104 long key) { 2105 synchronized (mAccessLock) { 2106 WeakReference<Drawable.ConstantState> wr = drawableCache.get(key); 2107 if (wr != null) { // we have the key 2108 Drawable.ConstantState entry = wr.get(); 2109 if (entry != null) { 2110 //Log.i(TAG, "Returning cached drawable @ #" + 2111 // Integer.toHexString(((Integer)key).intValue()) 2112 // + " in " + this + ": " + entry); 2113 return entry.newDrawable(this); 2114 } 2115 else { // our entry has been purged 2116 drawableCache.delete(key); 2117 } 2118 } 2119 } 2120 return null; 2121 } 2122 2123 /*package*/ ColorStateList loadColorStateList(TypedValue value, int id) 2124 throws NotFoundException { 2125 if (TRACE_FOR_PRELOAD) { 2126 // Log only framework resources 2127 if ((id >>> 24) == 0x1) { 2128 final String name = getResourceName(id); 2129 if (name != null) android.util.Log.d("PreloadColorStateList", name); 2130 } 2131 } 2132 2133 final long key = (((long) value.assetCookie) << 32) | value.data; 2134 2135 ColorStateList csl; 2136 2137 if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT && 2138 value.type <= TypedValue.TYPE_LAST_COLOR_INT) { 2139 2140 csl = sPreloadedColorStateLists.get(key); 2141 if (csl != null) { 2142 return csl; 2143 } 2144 2145 csl = ColorStateList.valueOf(value.data); 2146 if (mPreloading) { 2147 if (verifyPreloadConfig(value, "color")) { 2148 sPreloadedColorStateLists.put(key, csl); 2149 } 2150 } 2151 2152 return csl; 2153 } 2154 2155 csl = getCachedColorStateList(key); 2156 if (csl != null) { 2157 return csl; 2158 } 2159 2160 csl = sPreloadedColorStateLists.get(key); 2161 if (csl != null) { 2162 return csl; 2163 } 2164 2165 if (value.string == null) { 2166 throw new NotFoundException( 2167 "Resource is not a ColorStateList (color or path): " + value); 2168 } 2169 2170 String file = value.string.toString(); 2171 2172 if (file.endsWith(".xml")) { 2173 try { 2174 XmlResourceParser rp = loadXmlResourceParser( 2175 file, id, value.assetCookie, "colorstatelist"); 2176 csl = ColorStateList.createFromXml(this, rp); 2177 rp.close(); 2178 } catch (Exception e) { 2179 NotFoundException rnf = new NotFoundException( 2180 "File " + file + " from color state list resource ID #0x" 2181 + Integer.toHexString(id)); 2182 rnf.initCause(e); 2183 throw rnf; 2184 } 2185 } else { 2186 throw new NotFoundException( 2187 "File " + file + " from drawable resource ID #0x" 2188 + Integer.toHexString(id) + ": .xml extension required"); 2189 } 2190 2191 if (csl != null) { 2192 if (mPreloading) { 2193 if (verifyPreloadConfig(value, "color")) { 2194 sPreloadedColorStateLists.put(key, csl); 2195 } 2196 } else { 2197 synchronized (mAccessLock) { 2198 //Log.i(TAG, "Saving cached color state list @ #" + 2199 // Integer.toHexString(key.intValue()) 2200 // + " in " + this + ": " + csl); 2201 mColorStateListCache.put(key, new WeakReference<ColorStateList>(csl)); 2202 } 2203 } 2204 } 2205 2206 return csl; 2207 } 2208 2209 private ColorStateList getCachedColorStateList(long key) { 2210 synchronized (mAccessLock) { 2211 WeakReference<ColorStateList> wr = mColorStateListCache.get(key); 2212 if (wr != null) { // we have the key 2213 ColorStateList entry = wr.get(); 2214 if (entry != null) { 2215 //Log.i(TAG, "Returning cached color state list @ #" + 2216 // Integer.toHexString(((Integer)key).intValue()) 2217 // + " in " + this + ": " + entry); 2218 return entry; 2219 } else { // our entry has been purged 2220 mColorStateListCache.delete(key); 2221 } 2222 } 2223 } 2224 return null; 2225 } 2226 2227 /*package*/ XmlResourceParser loadXmlResourceParser(int id, String type) 2228 throws NotFoundException { 2229 synchronized (mAccessLock) { 2230 TypedValue value = mTmpValue; 2231 if (value == null) { 2232 mTmpValue = value = new TypedValue(); 2233 } 2234 getValue(id, value, true); 2235 if (value.type == TypedValue.TYPE_STRING) { 2236 return loadXmlResourceParser(value.string.toString(), id, 2237 value.assetCookie, type); 2238 } 2239 throw new NotFoundException( 2240 "Resource ID #0x" + Integer.toHexString(id) + " type #0x" 2241 + Integer.toHexString(value.type) + " is not valid"); 2242 } 2243 } 2244 2245 /*package*/ XmlResourceParser loadXmlResourceParser(String file, int id, 2246 int assetCookie, String type) throws NotFoundException { 2247 if (id != 0) { 2248 try { 2249 // These may be compiled... 2250 synchronized (mCachedXmlBlockIds) { 2251 // First see if this block is in our cache. 2252 final int num = mCachedXmlBlockIds.length; 2253 for (int i=0; i<num; i++) { 2254 if (mCachedXmlBlockIds[i] == id) { 2255 //System.out.println("**** REUSING XML BLOCK! id=" 2256 // + id + ", index=" + i); 2257 return mCachedXmlBlocks[i].newParser(); 2258 } 2259 } 2260 2261 // Not in the cache, create a new block and put it at 2262 // the next slot in the cache. 2263 XmlBlock block = mAssets.openXmlBlockAsset( 2264 assetCookie, file); 2265 if (block != null) { 2266 int pos = mLastCachedXmlBlockIndex+1; 2267 if (pos >= num) pos = 0; 2268 mLastCachedXmlBlockIndex = pos; 2269 XmlBlock oldBlock = mCachedXmlBlocks[pos]; 2270 if (oldBlock != null) { 2271 oldBlock.close(); 2272 } 2273 mCachedXmlBlockIds[pos] = id; 2274 mCachedXmlBlocks[pos] = block; 2275 //System.out.println("**** CACHING NEW XML BLOCK! id=" 2276 // + id + ", index=" + pos); 2277 return block.newParser(); 2278 } 2279 } 2280 } catch (Exception e) { 2281 NotFoundException rnf = new NotFoundException( 2282 "File " + file + " from xml type " + type + " resource ID #0x" 2283 + Integer.toHexString(id)); 2284 rnf.initCause(e); 2285 throw rnf; 2286 } 2287 } 2288 2289 throw new NotFoundException( 2290 "File " + file + " from xml type " + type + " resource ID #0x" 2291 + Integer.toHexString(id)); 2292 } 2293 2294 private TypedArray getCachedStyledAttributes(int len) { 2295 synchronized (mAccessLock) { 2296 TypedArray attrs = mCachedStyledAttributes; 2297 if (attrs != null) { 2298 mCachedStyledAttributes = null; 2299 if (DEBUG_ATTRIBUTES_CACHE) { 2300 mLastRetrievedAttrs = new RuntimeException("here"); 2301 mLastRetrievedAttrs.fillInStackTrace(); 2302 } 2303 2304 attrs.mLength = len; 2305 int fullLen = len * AssetManager.STYLE_NUM_ENTRIES; 2306 if (attrs.mData.length >= fullLen) { 2307 return attrs; 2308 } 2309 attrs.mData = new int[fullLen]; 2310 attrs.mIndices = new int[1+len]; 2311 return attrs; 2312 } 2313 if (DEBUG_ATTRIBUTES_CACHE) { 2314 RuntimeException here = new RuntimeException("here"); 2315 here.fillInStackTrace(); 2316 if (mLastRetrievedAttrs != null) { 2317 Log.i(TAG, "Allocated new TypedArray of " + len + " in " + this, here); 2318 Log.i(TAG, "Last retrieved attributes here", mLastRetrievedAttrs); 2319 } 2320 mLastRetrievedAttrs = here; 2321 } 2322 return new TypedArray(this, 2323 new int[len*AssetManager.STYLE_NUM_ENTRIES], 2324 new int[1+len], len); 2325 } 2326 } 2327 2328 private Resources() { 2329 mAssets = AssetManager.getSystem(); 2330 // NOTE: Intentionally leaving this uninitialized (all values set 2331 // to zero), so that anyone who tries to do something that requires 2332 // metrics will get a very wrong value. 2333 mConfiguration.setToDefaults(); 2334 mMetrics.setToDefaults(); 2335 updateConfiguration(null, null); 2336 mAssets.ensureStringBlocks(); 2337 mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; 2338 } 2339} 2340