blob: 8f58891ed556ee3c0246b9dbd46151c98d8beb3d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content.res;
18
Alan Viverette45c4bbb2015-01-05 14:59:19 -080019import android.animation.Animator;
20import android.animation.StateListAnimator;
Tor Norbye7b9c9122013-05-30 16:48:33 -070021import android.annotation.AnimRes;
ztenghuib5292562017-07-11 16:03:36 -070022import android.annotation.AnimatorRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070023import android.annotation.AnyRes;
24import android.annotation.ArrayRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070025import android.annotation.AttrRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070026import android.annotation.BoolRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070027import android.annotation.ColorInt;
Tor Norbye7b9c9122013-05-30 16:48:33 -070028import android.annotation.ColorRes;
29import android.annotation.DimenRes;
30import android.annotation.DrawableRes;
Clara Bayarried00bfd2017-01-20 14:58:21 +000031import android.annotation.FontRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070032import android.annotation.FractionRes;
33import android.annotation.IntegerRes;
34import android.annotation.LayoutRes;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080035import android.annotation.NonNull;
Alan Viverette3b5c4272014-05-20 13:20:42 -070036import android.annotation.Nullable;
Tor Norbye7b9c9122013-05-30 16:48:33 -070037import android.annotation.PluralsRes;
38import android.annotation.RawRes;
39import android.annotation.StringRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070040import android.annotation.StyleRes;
41import android.annotation.StyleableRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070042import android.annotation.XmlRes;
Dianne Hackbornebff8f92011-05-12 18:07:47 -070043import android.content.pm.ActivityInfo;
Alan Viverette9ad386b2017-01-26 14:00:20 -050044import android.content.pm.ActivityInfo.Config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.graphics.Movie;
Clara Bayarri18e9f9f2016-12-19 16:20:29 +000046import android.graphics.Typeface;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080047import android.graphics.drawable.Drawable;
Masanori Oginoc7d9d272010-07-10 12:10:41 +090048import android.graphics.drawable.Drawable.ConstantState;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070049import android.graphics.drawable.DrawableInflater;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070050import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.util.AttributeSet;
53import android.util.DisplayMetrics;
54import android.util.Log;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080055import android.util.LongSparseArray;
56import android.util.Pools.SynchronizedPool;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.util.TypedValue;
Adam Lesinski4ece3d62016-06-16 18:05:41 -070058import android.view.DisplayAdjustments;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080059import android.view.ViewDebug;
Siva Velusamy0d857b92015-04-22 10:23:56 -070060import android.view.ViewHierarchyEncoder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Adam Lesinski082614c2016-03-04 14:33:47 -080062import com.android.internal.annotations.VisibleForTesting;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070063import com.android.internal.util.GrowingArrayUtils;
64import com.android.internal.util.XmlUtils;
65
66import org.xmlpull.v1.XmlPullParser;
67import org.xmlpull.v1.XmlPullParserException;
68
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import java.io.IOException;
70import java.io.InputStream;
Adam Lesinski082614c2016-03-04 14:33:47 -080071import java.lang.ref.WeakReference;
72import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74/**
75 * Class for accessing an application's resources. This sits on top of the
Scott Mainf4f05b82011-01-07 14:38:23 -080076 * asset manager of the application (accessible through {@link #getAssets}) and
77 * provides a high-level API for getting typed data from the assets.
78 *
79 * <p>The Android resource system keeps track of all non-code assets associated with an
80 * application. You can use this class to access your application's resources. You can generally
81 * acquire the {@link android.content.res.Resources} instance associated with your application
82 * with {@link android.content.Context#getResources getResources()}.</p>
83 *
84 * <p>The Android SDK tools compile your application's resources into the application binary
85 * at build time. To use a resource, you must install it correctly in the source tree (inside
86 * your project's {@code res/} directory) and build your application. As part of the build
87 * process, the SDK tools generate symbols for each resource, which you can use in your application
88 * code to access the resources.</p>
89 *
90 * <p>Using application resources makes it easy to update various characteristics of your
91 * application without modifying code, and&mdash;by providing sets of alternative
92 * resources&mdash;enables you to optimize your application for a variety of device configurations
93 * (such as for different languages and screen sizes). This is an important aspect of developing
94 * Android applications that are compatible on different types of devices.</p>
95 *
96 * <p>For more information about using resources, see the documentation about <a
97 * href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 */
99public class Resources {
100 static final String TAG = "Resources";
Alan Viverette562a6a82014-01-31 11:07:29 -0800101
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800102 private static final Object sSync = new Object();
Fabrice Di Megliob9a13b82013-04-15 14:05:30 -0700103
Alan Viveretteedc46642014-02-01 01:43:16 -0800104 // Used by BridgeResources in layoutlib
105 static Resources mSystem = null;
106
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800107 private ResourcesImpl mResourcesImpl;
Alan Viverette4d07bc92015-11-16 10:19:12 -0500108
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800109 // Pool of TypedArrays targeted to this Resources object.
110 final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400112 /** Used to inflate drawable objects from XML. */
113 private DrawableInflater mDrawableInflater;
114
Alan Viverette4d07bc92015-11-16 10:19:12 -0500115 /** Lock object used to protect access to {@link #mTmpValue}. */
116 private final Object mTmpValueLock = new Object();
117
118 /** Single-item pool used to minimize TypedValue allocations. */
Alan Viverette562a6a82014-01-31 11:07:29 -0800119 private TypedValue mTmpValue = new TypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500120
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400121 final ClassLoader mClassLoader;
Fabrice Di Megliob9a13b82013-04-15 14:05:30 -0700122
Alan Viverette62599332014-04-01 14:57:39 -0700123 /**
Adam Lesinski082614c2016-03-04 14:33:47 -0800124 * WeakReferences to Themes that were constructed from this Resources object.
125 * We keep track of these in case our underlying implementation is changed, in which case
126 * the Themes must also get updated ThemeImpls.
127 */
128 private final ArrayList<WeakReference<Theme>> mThemeRefs = new ArrayList<>();
129
130 /**
Alan Viverette62599332014-04-01 14:57:39 -0700131 * Returns the most appropriate default theme for the specified target SDK version.
Alan Viverette5effd7e2014-05-05 12:25:33 -0700132 * <ul>
133 * <li>Below API 11: Gingerbread
Alan Viverette4b2b6152016-06-08 11:45:15 -0400134 * <li>APIs 12 thru 14: Holo
135 * <li>APIs 15 thru 23: Device default dark
136 * <li>APIs 24 and above: Device default light with dark action bar
Alan Viverette5effd7e2014-05-05 12:25:33 -0700137 * </ul>
Alan Viverette62599332014-04-01 14:57:39 -0700138 *
139 * @param curTheme The current theme, or 0 if not specified.
140 * @param targetSdkVersion The target SDK version.
141 * @return A theme resource identifier
142 * @hide
143 */
Alan Viverette5effd7e2014-05-05 12:25:33 -0700144 public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800145 return selectSystemTheme(curTheme, targetSdkVersion,
Alan Viverette5effd7e2014-05-05 12:25:33 -0700146 com.android.internal.R.style.Theme,
147 com.android.internal.R.style.Theme_Holo,
148 com.android.internal.R.style.Theme_DeviceDefault,
149 com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800150 }
Alan Viverette62599332014-04-01 14:57:39 -0700151
Alan Viverette5effd7e2014-05-05 12:25:33 -0700152 /** @hide */
153 public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo,
154 int dark, int deviceDefault) {
Adam Lesinski9553fb32017-05-23 18:53:44 -0700155 if (curTheme != ResourceId.ID_NULL) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800156 return curTheme;
157 }
Alan Viverette5effd7e2014-05-05 12:25:33 -0700158 if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
159 return orig;
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800160 }
Alan Viverette5effd7e2014-05-05 12:25:33 -0700161 if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
162 return holo;
163 }
Alan Viverette4b2b6152016-06-08 11:45:15 -0400164 if (targetSdkVersion < Build.VERSION_CODES.N) {
Alan Viverette5effd7e2014-05-05 12:25:33 -0700165 return dark;
166 }
167 return deviceDefault;
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800168 }
Alan Viverette62599332014-04-01 14:57:39 -0700169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800171 * Return a global shared Resources object that provides access to only
172 * system resources (no application resources), and is not configured for
173 * the current screen (can not use dimension units, does not change based
174 * on orientation, etc).
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400175 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800176 public static Resources getSystem() {
177 synchronized (sSync) {
178 Resources ret = mSystem;
179 if (ret == null) {
180 ret = new Resources();
181 mSystem = ret;
182 }
183 return ret;
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400184 }
Yigit Boyard422dc32014-09-25 12:23:35 -0700185 }
186
187 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 * This exception is thrown by the resource APIs when a requested resource
189 * can not be found.
190 */
191 public static class NotFoundException extends RuntimeException {
192 public NotFoundException() {
193 }
194
195 public NotFoundException(String name) {
196 super(name);
197 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500198
199 public NotFoundException(String name, Exception cause) {
200 super(name, cause);
201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 }
203
204 /**
205 * Create a new Resources object on top of an existing set of assets in an
206 * AssetManager.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800207 *
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -0700208 * @deprecated Resources should not be constructed by apps.
209 * See {@link android.content.Context#createConfigurationContext(Configuration)}.
210 *
Wale Ogunwale60454db2015-01-23 16:05:07 -0800211 * @param assets Previously created AssetManager.
212 * @param metrics Current display metrics to consider when
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 * selecting/computing resource values.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800214 * @param config Desired device configuration to consider when
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 * selecting/computing resource values (optional).
216 */
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -0700217 @Deprecated
Romain Guy5d911c32012-04-12 16:25:17 -0700218 public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800219 this(null);
Adam Lesinski8e8d2322016-06-24 12:29:16 -0700220 mResourcesImpl = new ResourcesImpl(assets, metrics, config, new DisplayAdjustments());
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700221 }
222
223 /**
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -0700224 * Creates a new Resources object with CompatibilityInfo.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800225 *
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400226 * @param classLoader class loader for the package used to load custom
227 * resource classes, may be {@code null} to use system
228 * class loader
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700229 * @hide
230 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800231 public Resources(@Nullable ClassLoader classLoader) {
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400232 mClassLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader;
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700233 }
234
235 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800236 * Only for creating the System resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800238 private Resources() {
239 this(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800241 final DisplayMetrics metrics = new DisplayMetrics();
242 metrics.setToDefaults();
243
244 final Configuration config = new Configuration();
245 config.setToDefaults();
246
247 mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
Adam Lesinski8e8d2322016-06-24 12:29:16 -0700248 new DisplayAdjustments());
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800249 }
250
251 /**
Adam Lesinski082614c2016-03-04 14:33:47 -0800252 * Set the underlying implementation (containing all the resources and caches)
253 * and updates all Theme references to new implementations as well.
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800254 * @hide
255 */
256 public void setImpl(ResourcesImpl impl) {
Adam Lesinski082614c2016-03-04 14:33:47 -0800257 if (impl == mResourcesImpl) {
258 return;
259 }
260
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800261 mResourcesImpl = impl;
Adam Lesinski082614c2016-03-04 14:33:47 -0800262
263 // Create new ThemeImpls that are identical to the ones we have.
264 synchronized (mThemeRefs) {
265 final int count = mThemeRefs.size();
266 for (int i = 0; i < count; i++) {
267 WeakReference<Theme> weakThemeRef = mThemeRefs.get(i);
268 Theme theme = weakThemeRef != null ? weakThemeRef.get() : null;
269 if (theme != null) {
270 theme.setImpl(mResourcesImpl.newThemeImpl(theme.getKey()));
271 }
272 }
273 }
274 }
275
276 /**
277 * @hide
278 */
279 public ResourcesImpl getImpl() {
280 return mResourcesImpl;
281 }
282
283 /**
284 * @hide
285 */
286 public ClassLoader getClassLoader() {
287 return mClassLoader;
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800288 }
289
290 /**
291 * @return the inflater used to create drawable objects
292 * @hide Pending API finalization.
293 */
294 public final DrawableInflater getDrawableInflater() {
295 if (mDrawableInflater == null) {
296 mDrawableInflater = new DrawableInflater(this, mClassLoader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800298 return mDrawableInflater;
299 }
300
301 /**
302 * Used by AnimatorInflater.
303 *
304 * @hide
305 */
306 public ConfigurationBoundResourceCache<Animator> getAnimatorCache() {
307 return mResourcesImpl.getAnimatorCache();
308 }
309
310 /**
311 * Used by AnimatorInflater.
312 *
313 * @hide
314 */
315 public ConfigurationBoundResourceCache<StateListAnimator> getStateListAnimatorCache() {
316 return mResourcesImpl.getStateListAnimatorCache();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
318
319 /**
320 * Return the string value associated with a particular resource ID. The
321 * returned object will be a String if this is a plain string; it will be
322 * some other type of CharSequence if it is styled.
323 * {@more}
324 *
325 * @param id The desired resource identifier, as generated by the aapt
326 * tool. This integer encodes the package, type, and resource
327 * entry. The value 0 is an invalid identifier.
328 *
329 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
330 *
331 * @return CharSequence The string data associated with the resource, plus
332 * possibly styled text information.
333 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800334 @NonNull public CharSequence getText(@StringRes int id) throws NotFoundException {
335 CharSequence res = mResourcesImpl.getAssets().getResourceText(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 if (res != null) {
337 return res;
338 }
339 throw new NotFoundException("String resource ID #0x"
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000340 + Integer.toHexString(id));
341 }
342
343 /**
344 * Return the Typeface value associated with a particular resource ID.
345 * {@more}
346 *
347 * @param id The desired resource identifier, as generated by the aapt
348 * tool. This integer encodes the package, type, and resource
349 * entry. The value 0 is an invalid identifier.
350 *
351 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
352 *
353 * @return Typeface The Typeface data associated with the resource.
354 */
Clara Bayarried00bfd2017-01-20 14:58:21 +0000355 @NonNull public Typeface getFont(@FontRes int id) throws NotFoundException {
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000356 final TypedValue value = obtainTempTypedValue();
357 try {
358 final ResourcesImpl impl = mResourcesImpl;
359 impl.getValue(id, value, true);
Clara Bayarried00bfd2017-01-20 14:58:21 +0000360 Typeface typeface = impl.loadFont(this, value, id);
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000361 if (typeface != null) {
362 return typeface;
363 }
364 } finally {
365 releaseTempTypedValue(value);
366 }
367 throw new NotFoundException("Font resource ID #0x"
368 + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 }
370
Clara Bayarried00bfd2017-01-20 14:58:21 +0000371 @NonNull
372 Typeface getFont(@NonNull TypedValue value, @FontRes int id) throws NotFoundException {
373 return mResourcesImpl.loadFont(this, value, id);
374 }
375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 /**
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000377 * @hide
378 */
Clara Bayarri2821eea2017-03-17 17:38:50 +0000379 public void preloadFonts(@ArrayRes int id) {
380 final TypedArray array = obtainTypedArray(id);
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000381 try {
Clara Bayarri2821eea2017-03-17 17:38:50 +0000382 final int size = array.length();
383 for (int i = 0; i < size; i++) {
384 array.getFont(i);
385 }
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000386 } finally {
Clara Bayarri2821eea2017-03-17 17:38:50 +0000387 array.recycle();
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000388 }
389 }
390
391 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800392 * Returns the character sequence necessary for grammatically correct pluralization
393 * of the given resource ID for the given quantity.
394 * Note that the character sequence is selected based solely on grammatical necessity,
395 * and that such rules differ between languages. Do not assume you know which string
396 * will be returned for a given quantity. See
397 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
398 * for more detail.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700399 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 * @param id The desired resource identifier, as generated by the aapt
401 * tool. This integer encodes the package, type, and resource
402 * entry. The value 0 is an invalid identifier.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700403 * @param quantity The number used to get the correct string for the current language's
404 * plural rules.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 *
406 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
407 *
408 * @return CharSequence The string data associated with the resource, plus
409 * possibly styled text information.
410 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800411 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700412 public CharSequence getQuantityText(@PluralsRes int id, int quantity)
413 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800414 return mResourcesImpl.getQuantityText(id, quantity);
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700415 }
416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 /**
418 * Return the string value associated with a particular resource ID. It
419 * will be stripped of any styled text information.
420 * {@more}
421 *
422 * @param id The desired resource identifier, as generated by the aapt
423 * tool. This integer encodes the package, type, and resource
424 * entry. The value 0 is an invalid identifier.
425 *
426 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
427 *
428 * @return String The string data associated with the resource,
Alan Viveretteb4004df2015-04-29 16:55:42 -0700429 * stripped of styled text information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 */
Alan Viveretteb4004df2015-04-29 16:55:42 -0700431 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700432 public String getString(@StringRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800433 return getText(id).toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 }
435
436
437 /**
438 * Return the string value associated with a particular resource ID,
439 * substituting the format arguments as defined in {@link java.util.Formatter}
440 * and {@link java.lang.String#format}. It will be stripped of any styled text
441 * information.
442 * {@more}
443 *
444 * @param id The desired resource identifier, as generated by the aapt
445 * tool. This integer encodes the package, type, and resource
446 * entry. The value 0 is an invalid identifier.
447 *
448 * @param formatArgs The format arguments that will be used for substitution.
449 *
450 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
451 *
452 * @return String The string data associated with the resource,
Alan Viveretteb4004df2015-04-29 16:55:42 -0700453 * stripped of styled text information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 */
Alan Viveretteb4004df2015-04-29 16:55:42 -0700455 @NonNull
456 public String getString(@StringRes int id, Object... formatArgs) throws NotFoundException {
457 final String raw = getString(id);
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800458 return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
459 formatArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 }
461
462 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800463 * Formats the string necessary for grammatically correct pluralization
464 * of the given resource ID for the given quantity, using the given arguments.
465 * Note that the string is selected based solely on grammatical necessity,
466 * and that such rules differ between languages. Do not assume you know which string
467 * will be returned for a given quantity. See
468 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
469 * for more detail.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 *
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800471 * <p>Substitution of format arguments works as if using
472 * {@link java.util.Formatter} and {@link java.lang.String#format}.
473 * The resulting string will be stripped of any styled text information.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700474 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 * @param id The desired resource identifier, as generated by the aapt
476 * tool. This integer encodes the package, type, and resource
477 * entry. The value 0 is an invalid identifier.
478 * @param quantity The number used to get the correct string for the current language's
479 * plural rules.
480 * @param formatArgs The format arguments that will be used for substitution.
481 *
482 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
483 *
484 * @return String The string data associated with the resource,
485 * stripped of styled text information.
486 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800487 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700488 public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 throws NotFoundException {
490 String raw = getQuantityText(id, quantity).toString();
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800491 return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
492 formatArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 }
494
495 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800496 * Returns the string necessary for grammatically correct pluralization
497 * of the given resource ID for the given quantity.
498 * Note that the string is selected based solely on grammatical necessity,
499 * and that such rules differ between languages. Do not assume you know which string
500 * will be returned for a given quantity. See
501 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
502 * for more detail.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700503 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 * @param id The desired resource identifier, as generated by the aapt
505 * tool. This integer encodes the package, type, and resource
506 * entry. The value 0 is an invalid identifier.
507 * @param quantity The number used to get the correct string for the current language's
508 * plural rules.
509 *
510 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
511 *
512 * @return String The string data associated with the resource,
513 * stripped of styled text information.
514 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800515 @NonNull
516 public String getQuantityString(@PluralsRes int id, int quantity) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 return getQuantityText(id, quantity).toString();
518 }
519
520 /**
521 * Return the string value associated with a particular resource ID. The
522 * returned object will be a String if this is a plain string; it will be
523 * some other type of CharSequence if it is styled.
524 *
525 * @param id The desired resource identifier, as generated by the aapt
526 * tool. This integer encodes the package, type, and resource
527 * entry. The value 0 is an invalid identifier.
528 *
529 * @param def The default CharSequence to return.
530 *
531 * @return CharSequence The string data associated with the resource, plus
532 * possibly styled text information, or def if id is 0 or not found.
533 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700534 public CharSequence getText(@StringRes int id, CharSequence def) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800535 CharSequence res = id != 0 ? mResourcesImpl.getAssets().getResourceText(id) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 return res != null ? res : def;
537 }
538
539 /**
540 * Return the styled text array associated with a particular resource ID.
541 *
542 * @param id The desired resource identifier, as generated by the aapt
543 * tool. This integer encodes the package, type, and resource
544 * entry. The value 0 is an invalid identifier.
545 *
546 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
547 *
548 * @return The styled text array associated with the resource.
549 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800550 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700551 public CharSequence[] getTextArray(@ArrayRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800552 CharSequence[] res = mResourcesImpl.getAssets().getResourceTextArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 if (res != null) {
554 return res;
555 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800556 throw new NotFoundException("Text array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 }
558
559 /**
560 * Return the string array associated with a particular resource ID.
561 *
562 * @param id The desired resource identifier, as generated by the aapt
563 * tool. This integer encodes the package, type, and resource
564 * entry. The value 0 is an invalid identifier.
565 *
566 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
567 *
568 * @return The string array associated with the resource.
569 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800570 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700571 public String[] getStringArray(@ArrayRes int id)
572 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800573 String[] res = mResourcesImpl.getAssets().getResourceStringArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 if (res != null) {
575 return res;
576 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800577 throw new NotFoundException("String array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 }
579
580 /**
581 * Return the int array associated with a particular resource ID.
582 *
583 * @param id The desired resource identifier, as generated by the aapt
584 * tool. This integer encodes the package, type, and resource
585 * entry. The value 0 is an invalid identifier.
586 *
587 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
588 *
589 * @return The int array associated with the resource.
590 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800591 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700592 public int[] getIntArray(@ArrayRes int id) throws NotFoundException {
Adam Lesinskidcb3c652017-01-23 12:58:11 -0800593 int[] res = mResourcesImpl.getAssets().getResourceIntArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 if (res != null) {
595 return res;
596 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800597 throw new NotFoundException("Int array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 }
599
600 /**
601 * Return an array of heterogeneous values.
602 *
603 * @param id The desired resource identifier, as generated by the aapt
604 * tool. This integer encodes the package, type, and resource
605 * entry. The value 0 is an invalid identifier.
606 *
607 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
608 *
609 * @return Returns a TypedArray holding an array of the array values.
610 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
611 * when done with it.
612 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800613 @NonNull
614 public TypedArray obtainTypedArray(@ArrayRes int id) throws NotFoundException {
615 final ResourcesImpl impl = mResourcesImpl;
Adam Lesinskidcb3c652017-01-23 12:58:11 -0800616 int len = impl.getAssets().getResourceArraySize(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 if (len < 0) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800618 throw new NotFoundException("Array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 }
620
Alan Viverette52b999f2014-03-24 18:00:26 -0700621 TypedArray array = TypedArray.obtain(this, len);
Adam Lesinskidcb3c652017-01-23 12:58:11 -0800622 array.mLength = impl.getAssets().getResourceArray(id, array.mData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 array.mIndices[0] = 0;
624
625 return array;
626 }
627
628 /**
629 * Retrieve a dimensional for a particular resource ID. Unit
630 * conversions are based on the current {@link DisplayMetrics} associated
631 * with the resources.
632 *
633 * @param id The desired resource identifier, as generated by the aapt
634 * tool. This integer encodes the package, type, and resource
635 * entry. The value 0 is an invalid identifier.
636 *
637 * @return Resource dimension value multiplied by the appropriate
638 * metric.
639 *
640 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
641 *
642 * @see #getDimensionPixelOffset
643 * @see #getDimensionPixelSize
644 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700645 public float getDimension(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800646 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500647 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800648 final ResourcesImpl impl = mResourcesImpl;
649 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800651 return TypedValue.complexToDimension(value.data, impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500653 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
654 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
655 } finally {
656 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657 }
658 }
659
660 /**
661 * Retrieve a dimensional for a particular resource ID for use
662 * as an offset in raw pixels. This is the same as
663 * {@link #getDimension}, except the returned value is converted to
664 * integer pixels for you. An offset conversion involves simply
665 * truncating the base value to an integer.
666 *
667 * @param id The desired resource identifier, as generated by the aapt
668 * tool. This integer encodes the package, type, and resource
669 * entry. The value 0 is an invalid identifier.
670 *
671 * @return Resource dimension value multiplied by the appropriate
672 * metric and truncated to integer pixels.
673 *
674 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
675 *
676 * @see #getDimension
677 * @see #getDimensionPixelSize
678 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700679 public int getDimensionPixelOffset(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800680 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500681 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800682 final ResourcesImpl impl = mResourcesImpl;
683 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800685 return TypedValue.complexToDimensionPixelOffset(value.data,
686 impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500688 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
689 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
690 } finally {
691 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 }
693 }
694
695 /**
696 * Retrieve a dimensional for a particular resource ID for use
697 * as a size in raw pixels. This is the same as
698 * {@link #getDimension}, except the returned value is converted to
699 * integer pixels for use as a size. A size conversion involves
700 * rounding the base value, and ensuring that a non-zero base value
701 * is at least one pixel in size.
702 *
703 * @param id The desired resource identifier, as generated by the aapt
704 * tool. This integer encodes the package, type, and resource
705 * entry. The value 0 is an invalid identifier.
706 *
707 * @return Resource dimension value multiplied by the appropriate
708 * metric and truncated to integer pixels.
709 *
710 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
711 *
712 * @see #getDimension
713 * @see #getDimensionPixelOffset
714 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700715 public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800716 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500717 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800718 final ResourcesImpl impl = mResourcesImpl;
719 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800721 return TypedValue.complexToDimensionPixelSize(value.data, impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500723 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
724 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
725 } finally {
726 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 }
728 }
729
730 /**
731 * Retrieve a fractional unit for a particular resource ID.
732 *
733 * @param id The desired resource identifier, as generated by the aapt
734 * tool. This integer encodes the package, type, and resource
735 * entry. The value 0 is an invalid identifier.
736 * @param base The base value of this fraction. In other words, a
737 * standard fraction is multiplied by this value.
738 * @param pbase The parent base value of this fraction. In other
739 * words, a parent fraction (nn%p) is multiplied by this
740 * value.
741 *
742 * @return Attribute fractional value multiplied by the appropriate
743 * base value.
744 *
745 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
746 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700747 public float getFraction(@FractionRes int id, int base, int pbase) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800748 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500749 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800750 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 if (value.type == TypedValue.TYPE_FRACTION) {
752 return TypedValue.complexToFraction(value.data, base, pbase);
753 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500754 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
755 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
756 } finally {
757 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 }
759 }
760
761 /**
762 * Return a drawable object associated with a particular resource ID.
763 * Various types of objects will be returned depending on the underlying
764 * resource -- for example, a solid color, PNG image, scalable image, etc.
765 * The Drawable API hides these implementation details.
Dianne Hackbornfb5c3db2012-05-18 15:24:24 -0700766 *
767 * <p class="note"><strong>Note:</strong> Prior to
768 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN}, this function
769 * would not correctly retrieve the final configuration density when
770 * the resource ID passed here is an alias to another Drawable resource.
771 * This means that if the density configuration of the alias resource
772 * is different than the actual resource, the density of the returned
Alan Viverette952802e2016-04-04 15:33:41 -0400773 * Drawable would be incorrect, resulting in bad scaling. To work
774 * around this, you can instead manually resolve the aliased reference
775 * by using {@link #getValue(int, TypedValue, boolean)} and passing
776 * {@code true} for {@code resolveRefs}. The resulting
777 * {@link TypedValue#resourceId} value may be passed to this method.</p>
Dianne Hackbornfb5c3db2012-05-18 15:24:24 -0700778 *
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700779 * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use
780 * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)}
781 * or {@link #getDrawable(int, Theme)} passing the desired theme.</p>
782 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 * @param id The desired resource identifier, as generated by the aapt
784 * tool. This integer encodes the package, type, and resource
785 * entry. The value 0 is an invalid identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 * @return Drawable An object that can be used to draw this resource.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800787 * @throws NotFoundException Throws NotFoundException if the given ID does
788 * not exist.
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700789 * @see #getDrawable(int, Theme)
Alan Viverettec10e3962014-12-02 14:58:08 -0800790 * @deprecated Use {@link #getDrawable(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 */
Alan Viverettec10e3962014-12-02 14:58:08 -0800792 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700793 public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
Alan Viverette34a14f962014-08-15 16:13:15 -0700794 final Drawable d = getDrawable(id, null);
Alan Viverette7e0aaae2014-11-24 11:27:09 -0800795 if (d != null && d.canApplyTheme()) {
Alan Viverette34a14f962014-08-15 16:13:15 -0700796 Log.w(TAG, "Drawable " + getResourceName(id) + " has unresolved theme "
797 + "attributes! Consider using Resources.getDrawable(int, Theme) or "
798 + "Context.getDrawable(int).", new RuntimeException());
799 }
800 return d;
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800801 }
802
803 /**
804 * Return a drawable object associated with a particular resource ID and
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700805 * styled for the specified theme. Various types of objects will be
806 * returned depending on the underlying resource -- for example, a solid
807 * color, PNG image, scalable image, etc.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800808 *
809 * @param id The desired resource identifier, as generated by the aapt
810 * tool. This integer encodes the package, type, and resource
811 * entry. The value 0 is an invalid identifier.
Alan Viverette3b5c4272014-05-20 13:20:42 -0700812 * @param theme The theme used to style the drawable attributes, may be {@code null}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800813 * @return Drawable An object that can be used to draw this resource.
814 * @throws NotFoundException Throws NotFoundException if the given ID does
815 * not exist.
816 */
Alan Viverette4d07bc92015-11-16 10:19:12 -0500817 public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
818 throws NotFoundException {
Adam Lesinski50954d22017-04-14 18:41:52 -0700819 return getDrawableForDensity(id, 0, theme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 }
821
822 /**
Kenny Root55fc8502010-10-28 14:47:01 -0700823 * Return a drawable object associated with a particular resource ID for the
824 * given screen density in DPI. This will set the drawable's density to be
825 * the device's density multiplied by the ratio of actual drawable density
826 * to requested density. This allows the drawable to be scaled up to the
827 * correct size if needed. Various types of objects will be returned
828 * depending on the underlying resource -- for example, a solid color, PNG
829 * image, scalable image, etc. The Drawable API hides these implementation
830 * details.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800831 *
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700832 * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use
833 * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)}
834 * or {@link #getDrawableForDensity(int, int, Theme)} passing the desired
835 * theme.</p>
836 *
Kenny Root55fc8502010-10-28 14:47:01 -0700837 * @param id The desired resource identifier, as generated by the aapt tool.
838 * This integer encodes the package, type, and resource entry.
839 * The value 0 is an invalid identifier.
840 * @param density the desired screen density indicated by the resource as
Adam Lesinski50954d22017-04-14 18:41:52 -0700841 * found in {@link DisplayMetrics}. A value of 0 means to use the
842 * density returned from {@link #getConfiguration()}.
843 * This is equivalent to calling {@link #getDrawable(int)}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800844 * @return Drawable An object that can be used to draw this resource.
Kenny Root55fc8502010-10-28 14:47:01 -0700845 * @throws NotFoundException Throws NotFoundException if the given ID does
846 * not exist.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800847 * @see #getDrawableForDensity(int, int, Theme)
Alan Viverettea6f8b2c2014-12-02 15:26:33 -0800848 * @deprecated Use {@link #getDrawableForDensity(int, int, Theme)} instead.
Kenny Root55fc8502010-10-28 14:47:01 -0700849 */
Alan Viverettea6f8b2c2014-12-02 15:26:33 -0800850 @Deprecated
Alan Viverette4d07bc92015-11-16 10:19:12 -0500851 public Drawable getDrawableForDensity(@DrawableRes int id, int density)
852 throws NotFoundException {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800853 return getDrawableForDensity(id, density, null);
854 }
855
856 /**
857 * Return a drawable object associated with a particular resource ID for the
858 * given screen density in DPI and styled for the specified theme.
859 *
860 * @param id The desired resource identifier, as generated by the aapt tool.
861 * This integer encodes the package, type, and resource entry.
862 * The value 0 is an invalid identifier.
863 * @param density The desired screen density indicated by the resource as
Adam Lesinski50954d22017-04-14 18:41:52 -0700864 * found in {@link DisplayMetrics}. A value of 0 means to use the
865 * density returned from {@link #getConfiguration()}.
866 * This is equivalent to calling {@link #getDrawable(int, Theme)}.
Alan Viverette3b5c4272014-05-20 13:20:42 -0700867 * @param theme The theme used to style the drawable attributes, may be {@code null}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800868 * @return Drawable An object that can be used to draw this resource.
869 * @throws NotFoundException Throws NotFoundException if the given ID does
870 * not exist.
871 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700872 public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800873 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500874 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800875 final ResourcesImpl impl = mResourcesImpl;
876 impl.getValueForDensity(id, density, value, true);
Adam Lesinski50954d22017-04-14 18:41:52 -0700877 return impl.loadDrawable(this, value, id, density, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -0500878 } finally {
879 releaseTempTypedValue(value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800880 }
Kenny Root55fc8502010-10-28 14:47:01 -0700881 }
882
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800883 @NonNull
Adam Lesinski50954d22017-04-14 18:41:52 -0700884 Drawable loadDrawable(@NonNull TypedValue value, int id, int density, @Nullable Theme theme)
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800885 throws NotFoundException {
Adam Lesinski50954d22017-04-14 18:41:52 -0700886 return mResourcesImpl.loadDrawable(this, value, id, density, theme);
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800887 }
888
Kenny Root55fc8502010-10-28 14:47:01 -0700889 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 * Return a movie object associated with the particular resource ID.
891 * @param id The desired resource identifier, as generated by the aapt
892 * tool. This integer encodes the package, type, and resource
893 * entry. The value 0 is an invalid identifier.
894 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
895 *
896 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700897 public Movie getMovie(@RawRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800898 final InputStream is = openRawResource(id);
899 final Movie movie = Movie.decodeStream(is);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 try {
901 is.close();
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800902 } catch (IOException e) {
903 // No one cares.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 }
905 return movie;
906 }
907
908 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800909 * Returns a color integer associated with a particular resource ID. If the
910 * resource holds a complex {@link ColorStateList}, then the default color
911 * from the set is returned.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 *
913 * @param id The desired resource identifier, as generated by the aapt
914 * tool. This integer encodes the package, type, and resource
915 * entry. The value 0 is an invalid identifier.
916 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800917 * @throws NotFoundException Throws NotFoundException if the given ID does
918 * not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800920 * @return A single color value in the form 0xAARRGGBB.
921 * @deprecated Use {@link #getColor(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 */
Tor Norbye80756e32015-03-02 09:39:27 -0800923 @ColorInt
Alan Viverette4a357cd2015-03-18 18:37:18 -0700924 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700925 public int getColor(@ColorRes int id) throws NotFoundException {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800926 return getColor(id, null);
927 }
928
929 /**
930 * Returns a themed color integer associated with a particular resource ID.
931 * If the resource holds a complex {@link ColorStateList}, then the default
932 * color from the set is returned.
933 *
934 * @param id The desired resource identifier, as generated by the aapt
935 * tool. This integer encodes the package, type, and resource
936 * entry. The value 0 is an invalid identifier.
937 * @param theme The theme used to style the color attributes, may be
938 * {@code null}.
939 *
940 * @throws NotFoundException Throws NotFoundException if the given ID does
941 * not exist.
942 *
943 * @return A single color value in the form 0xAARRGGBB.
944 */
Tor Norbye80756e32015-03-02 09:39:27 -0800945 @ColorInt
Tor Norbye7b9c9122013-05-30 16:48:33 -0700946 public int getColor(@ColorRes int id, @Nullable Theme theme) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800947 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500948 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800949 final ResourcesImpl impl = mResourcesImpl;
950 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800952 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 return value.data;
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800954 } else if (value.type != TypedValue.TYPE_STRING) {
Alan Viverette4d07bc92015-11-16 10:19:12 -0500955 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
956 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800958
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800959 final ColorStateList csl = impl.loadColorStateList(this, value, id, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -0500960 return csl.getDefaultColor();
961 } finally {
962 releaseTempTypedValue(value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 }
965
966 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800967 * Returns a color state list associated with a particular resource ID. The
968 * resource may contain either a single raw color value or a complex
969 * {@link ColorStateList} holding multiple possible colors.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 *
971 * @param id The desired resource identifier of a {@link ColorStateList},
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800972 * as generated by the aapt tool. This integer encodes the
973 * package, type, and resource entry. The value 0 is an invalid
974 * identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800976 * @throws NotFoundException Throws NotFoundException if the given ID does
977 * not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800979 * @return A ColorStateList object containing either a single solid color
980 * or multiple colors that can be selected based on a state.
981 * @deprecated Use {@link #getColorStateList(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 */
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800983 @Nullable
Alan Viverette4a357cd2015-03-18 18:37:18 -0700984 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700985 public ColorStateList getColorStateList(@ColorRes int id) throws NotFoundException {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800986 final ColorStateList csl = getColorStateList(id, null);
987 if (csl != null && csl.canApplyTheme()) {
988 Log.w(TAG, "ColorStateList " + getResourceName(id) + " has "
989 + "unresolved theme attributes! Consider using "
990 + "Resources.getColorStateList(int, Theme) or "
991 + "Context.getColorStateList(int).", new RuntimeException());
992 }
993 return csl;
994 }
995
996 /**
997 * Returns a themed color state list associated with a particular resource
998 * ID. The resource may contain either a single raw color value or a
999 * complex {@link ColorStateList} holding multiple possible colors.
1000 *
1001 * @param id The desired resource identifier of a {@link ColorStateList},
1002 * as generated by the aapt tool. This integer encodes the
1003 * package, type, and resource entry. The value 0 is an invalid
1004 * identifier.
1005 * @param theme The theme used to style the color attributes, may be
1006 * {@code null}.
1007 *
1008 * @throws NotFoundException Throws NotFoundException if the given ID does
1009 * not exist.
1010 *
1011 * @return A themed ColorStateList object containing either a single solid
1012 * color or multiple colors that can be selected based on a state.
1013 */
1014 @Nullable
Tor Norbye7b9c9122013-05-30 16:48:33 -07001015 public ColorStateList getColorStateList(@ColorRes int id, @Nullable Theme theme)
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001016 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001017 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001018 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001019 final ResourcesImpl impl = mResourcesImpl;
1020 impl.getValue(id, value, true);
1021 return impl.loadColorStateList(this, value, id, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -05001022 } finally {
1023 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 }
1025 }
1026
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001027 @Nullable
1028 ColorStateList loadColorStateList(@NonNull TypedValue value, int id, @Nullable Theme theme)
1029 throws NotFoundException {
1030 return mResourcesImpl.loadColorStateList(this, value, id, theme);
1031 }
1032
Teng-Hui Zhue03c4692016-03-17 10:38:43 -07001033 /**
1034 * @hide
1035 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001036 @Nullable
1037 public ComplexColor loadComplexColor(@NonNull TypedValue value, int id, @Nullable Theme theme) {
1038 return mResourcesImpl.loadComplexColor(this, value, id, theme);
1039 }
1040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 /**
1042 * Return a boolean associated with a particular resource ID. This can be
1043 * used with any integral resource value, and will return true if it is
1044 * non-zero.
1045 *
1046 * @param id The desired resource identifier, as generated by the aapt
1047 * tool. This integer encodes the package, type, and resource
1048 * entry. The value 0 is an invalid identifier.
1049 *
1050 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1051 *
1052 * @return Returns the boolean value contained in the resource.
1053 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001054 public boolean getBoolean(@BoolRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001055 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001056 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001057 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette4d07bc92015-11-16 10:19:12 -05001059 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 return value.data != 0;
1061 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001062 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1063 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1064 } finally {
1065 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 }
1067 }
1068
1069 /**
1070 * Return an integer associated with a particular resource ID.
1071 *
1072 * @param id The desired resource identifier, as generated by the aapt
1073 * tool. This integer encodes the package, type, and resource
1074 * entry. The value 0 is an invalid identifier.
1075 *
1076 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1077 *
1078 * @return Returns the integer value contained in the resource.
1079 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001080 public int getInteger(@IntegerRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001081 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001082 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001083 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette4d07bc92015-11-16 10:19:12 -05001085 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 return value.data;
1087 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001088 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1089 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1090 } finally {
1091 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 }
1093 }
1094
1095 /**
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001096 * Retrieve a floating-point value for a particular resource ID.
1097 *
1098 * @param id The desired resource identifier, as generated by the aapt
1099 * tool. This integer encodes the package, type, and resource
1100 * entry. The value 0 is an invalid identifier.
1101 *
1102 * @return Returns the floating-point value contained in the resource.
1103 *
1104 * @throws NotFoundException Throws NotFoundException if the given ID does
1105 * not exist or is not a floating-point value.
1106 * @hide Pending API council approval.
1107 */
1108 public float getFloat(int id) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001109 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001110 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001111 mResourcesImpl.getValue(id, value, true);
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001112 if (value.type == TypedValue.TYPE_FLOAT) {
1113 return value.getFloat();
1114 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001115 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1116 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1117 } finally {
1118 releaseTempTypedValue(value);
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001119 }
1120 }
1121
1122 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 * Return an XmlResourceParser through which you can read a view layout
1124 * description for the given resource ID. This parser has limited
1125 * functionality -- in particular, you can't change its input, and only
1126 * the high-level events are available.
1127 *
1128 * <p>This function is really a simple wrapper for calling
1129 * {@link #getXml} with a layout resource.
1130 *
1131 * @param id The desired resource identifier, as generated by the aapt
1132 * tool. This integer encodes the package, type, and resource
1133 * entry. The value 0 is an invalid identifier.
1134 *
1135 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1136 *
1137 * @return A new parser object through which you can read
1138 * the XML data.
1139 *
1140 * @see #getXml
1141 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001142 public XmlResourceParser getLayout(@LayoutRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 return loadXmlResourceParser(id, "layout");
1144 }
1145
1146 /**
1147 * Return an XmlResourceParser through which you can read an animation
1148 * description for the given resource ID. This parser has limited
1149 * functionality -- in particular, you can't change its input, and only
1150 * the high-level events are available.
1151 *
1152 * <p>This function is really a simple wrapper for calling
1153 * {@link #getXml} with an animation resource.
1154 *
1155 * @param id The desired resource identifier, as generated by the aapt
1156 * tool. This integer encodes the package, type, and resource
1157 * entry. The value 0 is an invalid identifier.
1158 *
1159 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1160 *
1161 * @return A new parser object through which you can read
1162 * the XML data.
1163 *
1164 * @see #getXml
1165 */
ztenghuib5292562017-07-11 16:03:36 -07001166 public XmlResourceParser getAnimation(@AnimatorRes @AnimRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 return loadXmlResourceParser(id, "anim");
1168 }
1169
1170 /**
1171 * Return an XmlResourceParser through which you can read a generic XML
1172 * resource for the given resource ID.
1173 *
1174 * <p>The XmlPullParser implementation returned here has some limited
1175 * functionality. In particular, you can't change its input, and only
1176 * high-level parsing events are available (since the document was
1177 * pre-parsed for you at build time, which involved merging text and
1178 * stripping comments).
1179 *
1180 * @param id The desired resource identifier, as generated by the aapt
1181 * tool. This integer encodes the package, type, and resource
1182 * entry. The value 0 is an invalid identifier.
1183 *
1184 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1185 *
1186 * @return A new parser object through which you can read
1187 * the XML data.
1188 *
1189 * @see android.util.AttributeSet
1190 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001191 public XmlResourceParser getXml(@XmlRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 return loadXmlResourceParser(id, "xml");
1193 }
1194
1195 /**
1196 * Open a data stream for reading a raw resource. This can only be used
1197 * with resources whose value is the name of an asset files -- that is, it can be
1198 * used to open drawable, sound, and raw resources; it will fail on string
1199 * and color resources.
1200 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001201 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 *
1203 * @return InputStream Access to the resource data.
1204 *
1205 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1206 *
1207 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001208 public InputStream openRawResource(@RawRes int id) throws NotFoundException {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001209 final TypedValue value = obtainTempTypedValue();
1210 try {
1211 return openRawResource(id, value);
1212 } finally {
1213 releaseTempTypedValue(value);
1214 }
1215 }
1216
1217 /**
Alan Viverette4d07bc92015-11-16 10:19:12 -05001218 * Returns a TypedValue suitable for temporary use. The obtained TypedValue
1219 * should be released using {@link #releaseTempTypedValue(TypedValue)}.
1220 *
1221 * @return a typed value suitable for temporary use
1222 */
1223 private TypedValue obtainTempTypedValue() {
1224 TypedValue tmpValue = null;
1225 synchronized (mTmpValueLock) {
1226 if (mTmpValue != null) {
1227 tmpValue = mTmpValue;
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001228 mTmpValue = null;
1229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001231 if (tmpValue == null) {
1232 return new TypedValue();
1233 }
1234 return tmpValue;
1235 }
1236
1237 /**
1238 * Returns a TypedValue to the pool. After calling this method, the
1239 * specified TypedValue should no longer be accessed.
1240 *
1241 * @param value the typed value to return to the pool
1242 */
1243 private void releaseTempTypedValue(TypedValue value) {
1244 synchronized (mTmpValueLock) {
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001245 if (mTmpValue == null) {
1246 mTmpValue = value;
1247 }
1248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 }
1250
1251 /**
1252 * Open a data stream for reading a raw resource. This can only be used
Andy Stadlerf8a7cea2009-04-10 16:24:47 -07001253 * with resources whose value is the name of an asset file -- that is, it can be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 * used to open drawable, sound, and raw resources; it will fail on string
1255 * and color resources.
1256 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001257 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 * @param value The TypedValue object to hold the resource information.
1259 *
1260 * @return InputStream Access to the resource data.
1261 *
1262 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001264 public InputStream openRawResource(@RawRes int id, TypedValue value)
1265 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001266 return mResourcesImpl.openRawResource(id, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 }
1268
1269 /**
1270 * Open a file descriptor for reading a raw resource. This can only be used
1271 * with resources whose value is the name of an asset files -- that is, it can be
1272 * used to open drawable, sound, and raw resources; it will fail on string
1273 * and color resources.
1274 *
1275 * <p>This function only works for resources that are stored in the package
1276 * as uncompressed data, which typically includes things like mp3 files
1277 * and png images.
1278 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001279 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 *
1281 * @return AssetFileDescriptor A new file descriptor you can use to read
1282 * the resource. This includes the file descriptor itself, as well as the
1283 * offset and length of data where the resource appears in the file. A
1284 * null is returned if the file exists but is compressed.
1285 *
1286 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1287 *
1288 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001289 public AssetFileDescriptor openRawResourceFd(@RawRes int id)
1290 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001291 final TypedValue value = obtainTempTypedValue();
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001292 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001293 return mResourcesImpl.openRawResourceFd(id, value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001294 } finally {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001295 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 }
1297 }
1298
1299 /**
1300 * Return the raw data associated with a particular resource ID.
1301 *
1302 * @param id The desired resource identifier, as generated by the aapt
1303 * tool. This integer encodes the package, type, and resource
1304 * entry. The value 0 is an invalid identifier.
1305 * @param outValue Object in which to place the resource data.
1306 * @param resolveRefs If true, a resource that is a reference to another
1307 * resource will be followed so that you receive the
1308 * actual final resource data. If false, the TypedValue
1309 * will be filled in with the reference itself.
1310 *
1311 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1312 *
1313 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001314 public void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001316 mResourcesImpl.getValue(id, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 }
1318
1319 /**
Kenny Root55fc8502010-10-28 14:47:01 -07001320 * Get the raw value associated with a resource with associated density.
1321 *
1322 * @param id resource identifier
1323 * @param density density in DPI
1324 * @param resolveRefs If true, a resource that is a reference to another
1325 * resource will be followed so that you receive the actual final
1326 * resource data. If false, the TypedValue will be filled in with
1327 * the reference itself.
1328 * @throws NotFoundException Throws NotFoundException if the given ID does
1329 * not exist.
1330 * @see #getValue(String, TypedValue, boolean)
Kenny Root55fc8502010-10-28 14:47:01 -07001331 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001332 public void getValueForDensity(@AnyRes int id, int density, TypedValue outValue,
1333 boolean resolveRefs) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001334 mResourcesImpl.getValueForDensity(id, density, outValue, resolveRefs);
Kenny Root55fc8502010-10-28 14:47:01 -07001335 }
1336
1337 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 * Return the raw data associated with a particular resource ID.
1339 * See getIdentifier() for information on how names are mapped to resource
1340 * IDs, and getString(int) for information on how string resources are
1341 * retrieved.
1342 *
1343 * <p>Note: use of this function is discouraged. It is much more
1344 * efficient to retrieve resources by identifier than by name.
1345 *
1346 * @param name The name of the desired resource. This is passed to
1347 * getIdentifier() with a default type of "string".
1348 * @param outValue Object in which to place the resource data.
1349 * @param resolveRefs If true, a resource that is a reference to another
1350 * resource will be followed so that you receive the
1351 * actual final resource data. If false, the TypedValue
1352 * will be filled in with the reference itself.
1353 *
1354 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1355 *
1356 */
1357 public void getValue(String name, TypedValue outValue, boolean resolveRefs)
1358 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001359 mResourcesImpl.getValue(name, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 }
1361
1362 /**
1363 * This class holds the current attribute values for a particular theme.
1364 * In other words, a Theme is a set of values for resource attributes;
1365 * these are used in conjunction with {@link TypedArray}
1366 * to resolve the final value for an attribute.
1367 *
1368 * <p>The Theme's attributes come into play in two ways: (1) a styled
1369 * attribute can explicit reference a value in the theme through the
1370 * "?themeAttribute" syntax; (2) if no value has been defined for a
1371 * particular styled attribute, as a last resort we will try to find that
1372 * attribute's value in the Theme.
1373 *
1374 * <p>You will normally use the {@link #obtainStyledAttributes} APIs to
1375 * retrieve XML attributes with style and theme information applied.
1376 */
1377 public final class Theme {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001378 private ResourcesImpl.ThemeImpl mThemeImpl;
1379
1380 private Theme() {
1381 }
1382
1383 void setImpl(ResourcesImpl.ThemeImpl impl) {
1384 mThemeImpl = impl;
1385 }
1386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 /**
1388 * Place new attribute values into the theme. The style resource
1389 * specified by <var>resid</var> will be retrieved from this Theme's
1390 * resources, its values placed into the Theme object.
1391 *
1392 * <p>The semantics of this function depends on the <var>force</var>
1393 * argument: If false, only values that are not already defined in
1394 * the theme will be copied from the system resource; otherwise, if
1395 * any of the style's attributes are already defined in the theme, the
1396 * current values in the theme will be overwritten.
1397 *
Alan Viverette75257ce2014-05-22 19:31:38 -07001398 * @param resId The resource ID of a style resource from which to
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 * obtain attribute values.
1400 * @param force If true, values in the style resource will always be
1401 * used in the theme; otherwise, they will only be used
1402 * if not already defined in the theme.
1403 */
Alan Viverette75257ce2014-05-22 19:31:38 -07001404 public void applyStyle(int resId, boolean force) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001405 mThemeImpl.applyStyle(resId, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
1407
1408 /**
1409 * Set this theme to hold the same contents as the theme
1410 * <var>other</var>. If both of these themes are from the same
1411 * Resources object, they will be identical after this function
1412 * returns. If they are from different Resources, only the resources
1413 * they have in common will be set in this theme.
1414 *
1415 * @param other The existing Theme to copy from.
1416 */
1417 public void setTo(Theme other) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001418 mThemeImpl.setTo(other.mThemeImpl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 }
1420
1421 /**
John Spurlock330dd532012-12-18 12:03:11 -05001422 * Return a TypedArray holding the values defined by
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 * <var>Theme</var> which are listed in <var>attrs</var>.
1424 *
Scott Main183bf112012-08-13 19:12:13 -07001425 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1426 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 *
Adam Lesinski5ec88752017-04-12 14:45:14 -07001428 * @param attrs The desired attributes. These attribute IDs must be sorted in ascending
1429 * order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 *
1431 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1432 *
1433 * @return Returns a TypedArray holding an array of the attribute values.
1434 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1435 * when done with it.
1436 *
1437 * @see Resources#obtainAttributes
1438 * @see #obtainStyledAttributes(int, int[])
1439 * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
1440 */
Tor Norbyec91531a2015-04-01 17:41:55 -07001441 public TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001442 return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 }
1444
1445 /**
John Spurlock330dd532012-12-18 12:03:11 -05001446 * Return a TypedArray holding the values defined by the style
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 * resource <var>resid</var> which are listed in <var>attrs</var>.
1448 *
Scott Main183bf112012-08-13 19:12:13 -07001449 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1450 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 *
Alan Viverette395cd012015-08-11 17:27:04 -04001452 * @param resId The desired style resource.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001453 * @param attrs The desired attributes in the style. These attribute IDs must be sorted in
1454 * ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 *
1456 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1457 *
1458 * @return Returns a TypedArray holding an array of the attribute values.
1459 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1460 * when done with it.
1461 *
1462 * @see Resources#obtainAttributes
1463 * @see #obtainStyledAttributes(int[])
1464 * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
1465 */
Alan Viverette395cd012015-08-11 17:27:04 -04001466 public TypedArray obtainStyledAttributes(@StyleRes int resId, @StyleableRes int[] attrs)
Tor Norbyec91531a2015-04-01 17:41:55 -07001467 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001468 return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, resId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 }
1470
1471 /**
John Spurlock330dd532012-12-18 12:03:11 -05001472 * Return a TypedArray holding the attribute values in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 * <var>set</var>
1474 * that are listed in <var>attrs</var>. In addition, if the given
1475 * AttributeSet specifies a style class (through the "style" attribute),
1476 * that style will be applied on top of the base attributes it defines.
1477 *
Scott Main183bf112012-08-13 19:12:13 -07001478 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1479 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 *
1481 * <p>When determining the final value of a particular attribute, there
1482 * are four inputs that come into play:</p>
1483 *
1484 * <ol>
1485 * <li> Any attribute values in the given AttributeSet.
1486 * <li> The style resource specified in the AttributeSet (named
1487 * "style").
1488 * <li> The default style specified by <var>defStyleAttr</var> and
1489 * <var>defStyleRes</var>
1490 * <li> The base values in this theme.
1491 * </ol>
1492 *
1493 * <p>Each of these inputs is considered in-order, with the first listed
1494 * taking precedence over the following ones. In other words, if in the
1495 * AttributeSet you have supplied <code>&lt;Button
1496 * textColor="#ff000000"&gt;</code>, then the button's text will
1497 * <em>always</em> be black, regardless of what is specified in any of
1498 * the styles.
1499 *
1500 * @param set The base set of attribute values. May be null.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001501 * @param attrs The desired attributes to be retrieved. These attribute IDs must be sorted
1502 * in ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 * @param defStyleAttr An attribute in the current theme that contains a
1504 * reference to a style resource that supplies
John Spurlock330dd532012-12-18 12:03:11 -05001505 * defaults values for the TypedArray. Can be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 * 0 to not look for defaults.
1507 * @param defStyleRes A resource identifier of a style resource that
John Spurlock330dd532012-12-18 12:03:11 -05001508 * supplies default values for the TypedArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 * used only if defStyleAttr is 0 or can not be found
1510 * in the theme. Can be 0 to not look for defaults.
1511 *
1512 * @return Returns a TypedArray holding an array of the attribute values.
1513 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1514 * when done with it.
1515 *
1516 * @see Resources#obtainAttributes
1517 * @see #obtainStyledAttributes(int[])
1518 * @see #obtainStyledAttributes(int, int[])
1519 */
1520 public TypedArray obtainStyledAttributes(AttributeSet set,
Tor Norbyec91531a2015-04-01 17:41:55 -07001521 @StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001522 return mThemeImpl.obtainStyledAttributes(this, set, attrs, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 }
1524
1525 /**
Alan Viverette52b999f2014-03-24 18:00:26 -07001526 * Retrieve the values for a set of attributes in the Theme. The
1527 * contents of the typed array are ultimately filled in by
1528 * {@link Resources#getValue}.
1529 *
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001530 * @param values The base set of attribute values, must be equal in
1531 * length to {@code attrs}. All values must be of type
1532 * {@link TypedValue#TYPE_ATTRIBUTE}.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001533 * @param attrs The desired attributes to be retrieved. These attribute IDs must be sorted
1534 * in ascending order.
Alan Viverette52b999f2014-03-24 18:00:26 -07001535 * @return Returns a TypedArray holding an array of the attribute
1536 * values. Be sure to call {@link TypedArray#recycle()}
1537 * when done with it.
1538 * @hide
1539 */
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001540 @NonNull
1541 public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001542 return mThemeImpl.resolveAttributes(this, values, attrs);
Alan Viverette52b999f2014-03-24 18:00:26 -07001543 }
1544
1545 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 * Retrieve the value of an attribute in the Theme. The contents of
1547 * <var>outValue</var> are ultimately filled in by
1548 * {@link Resources#getValue}.
1549 *
1550 * @param resid The resource identifier of the desired theme
1551 * attribute.
1552 * @param outValue Filled in with the ultimate resource value supplied
1553 * by the attribute.
1554 * @param resolveRefs If true, resource references will be walked; if
1555 * false, <var>outValue</var> may be a
1556 * TYPE_REFERENCE. In either case, it will never
1557 * be a TYPE_ATTRIBUTE.
1558 *
1559 * @return boolean Returns true if the attribute was found and
1560 * <var>outValue</var> is valid, else false.
1561 */
Alan Viverette52b999f2014-03-24 18:00:26 -07001562 public boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001563 return mThemeImpl.resolveAttribute(resid, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 }
1565
1566 /**
Jon Miranda042ad632014-09-03 17:57:35 -07001567 * Gets all of the attribute ids associated with this {@link Theme}. For debugging only.
1568 *
1569 * @return The int array containing attribute ids associated with this {@link Theme}.
1570 * @hide
1571 */
1572 public int[] getAllAttributes() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001573 return mThemeImpl.getAllAttributes();
Jon Miranda042ad632014-09-03 17:57:35 -07001574 }
1575
1576 /**
Alan Viverette52b999f2014-03-24 18:00:26 -07001577 * Returns the resources to which this theme belongs.
1578 *
1579 * @return Resources to which this theme belongs.
1580 */
1581 public Resources getResources() {
1582 return Resources.this;
1583 }
1584
1585 /**
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001586 * Return a drawable object associated with a particular resource ID
1587 * and styled for the Theme.
1588 *
1589 * @param id The desired resource identifier, as generated by the aapt
1590 * tool. This integer encodes the package, type, and resource
1591 * entry. The value 0 is an invalid identifier.
1592 * @return Drawable An object that can be used to draw this resource.
1593 * @throws NotFoundException Throws NotFoundException if the given ID
1594 * does not exist.
1595 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001596 public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001597 return Resources.this.getDrawable(id, this);
1598 }
1599
1600 /**
Alan Viverettec1d52792015-05-05 09:49:03 -07001601 * Returns a bit mask of configuration changes that will impact this
1602 * theme (and thus require completely reloading it).
1603 *
1604 * @return a bit mask of configuration changes, as defined by
1605 * {@link ActivityInfo}
1606 * @see ActivityInfo
1607 */
Alan Viverette9ad386b2017-01-26 14:00:20 -05001608 public @Config int getChangingConfigurations() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001609 return mThemeImpl.getChangingConfigurations();
Alan Viverettec1d52792015-05-05 09:49:03 -07001610 }
1611
1612 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613 * Print contents of this theme out to the log. For debugging only.
1614 *
1615 * @param priority The log priority to use.
1616 * @param tag The log tag to use.
1617 * @param prefix Text to prefix each line printed.
1618 */
1619 public void dump(int priority, String tag, String prefix) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001620 mThemeImpl.dump(priority, tag, prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 }
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001622
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001623 // Needed by layoutlib.
1624 /*package*/ long getNativeTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001625 return mThemeImpl.getNativeTheme();
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001626 }
1627
1628 /*package*/ int getAppliedStyleResId() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001629 return mThemeImpl.getAppliedStyleResId();
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001630 }
Alan Viverette75257ce2014-05-22 19:31:38 -07001631
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001632 /**
1633 * @hide
1634 */
1635 public ThemeKey getKey() {
1636 return mThemeImpl.getKey();
Alan Viverette75257ce2014-05-22 19:31:38 -07001637 }
Jon Miranda836c0a82014-08-11 12:32:26 -07001638
1639 private String getResourceNameFromHexString(String hexString) {
1640 return getResourceName(Integer.parseInt(hexString, 16));
1641 }
1642
1643 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001644 * Parses {@link #getKey()} and returns a String array that holds pairs of
Alan Viverettee54d2452015-05-06 10:41:43 -07001645 * adjacent Theme data: resource name followed by whether or not it was
1646 * forced, as specified by {@link #applyStyle(int, boolean)}.
Jon Miranda836c0a82014-08-11 12:32:26 -07001647 *
1648 * @hide
1649 */
1650 @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
1651 public String[] getTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001652 return mThemeImpl.getTheme();
Jon Miranda836c0a82014-08-11 12:32:26 -07001653 }
Alan Viverettee54d2452015-05-06 10:41:43 -07001654
Siva Velusamy0d857b92015-04-22 10:23:56 -07001655 /** @hide */
1656 public void encode(@NonNull ViewHierarchyEncoder encoder) {
1657 encoder.beginObject(this);
Alan Viveretteac674092015-05-08 11:04:47 -07001658 final String[] properties = getTheme();
Siva Velusamy0d857b92015-04-22 10:23:56 -07001659 for (int i = 0; i < properties.length; i += 2) {
1660 encoder.addProperty(properties[i], properties[i+1]);
1661 }
1662 encoder.endObject();
1663 }
1664
Alan Viverettee54d2452015-05-06 10:41:43 -07001665 /**
1666 * Rebases the theme against the parent Resource object's current
1667 * configuration by re-applying the styles passed to
1668 * {@link #applyStyle(int, boolean)}.
1669 *
1670 * @hide
1671 */
1672 public void rebase() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001673 mThemeImpl.rebase();
Alan Viverettee54d2452015-05-06 10:41:43 -07001674 }
1675 }
1676
1677 static class ThemeKey implements Cloneable {
1678 int[] mResId;
1679 boolean[] mForce;
1680 int mCount;
1681
1682 private int mHashCode = 0;
1683
1684 public void append(int resId, boolean force) {
1685 if (mResId == null) {
1686 mResId = new int[4];
1687 }
1688
1689 if (mForce == null) {
1690 mForce = new boolean[4];
1691 }
1692
1693 mResId = GrowingArrayUtils.append(mResId, mCount, resId);
1694 mForce = GrowingArrayUtils.append(mForce, mCount, force);
1695 mCount++;
1696
1697 mHashCode = 31 * (31 * mHashCode + resId) + (force ? 1 : 0);
1698 }
1699
1700 /**
1701 * Sets up this key as a deep copy of another key.
1702 *
1703 * @param other the key to deep copy into this key
1704 */
1705 public void setTo(ThemeKey other) {
1706 mResId = other.mResId == null ? null : other.mResId.clone();
1707 mForce = other.mForce == null ? null : other.mForce.clone();
1708 mCount = other.mCount;
1709 }
1710
1711 @Override
1712 public int hashCode() {
1713 return mHashCode;
1714 }
1715
1716 @Override
1717 public boolean equals(Object o) {
1718 if (this == o) {
1719 return true;
1720 }
1721
1722 if (o == null || getClass() != o.getClass() || hashCode() != o.hashCode()) {
1723 return false;
1724 }
1725
1726 final ThemeKey t = (ThemeKey) o;
1727 if (mCount != t.mCount) {
1728 return false;
1729 }
1730
1731 final int N = mCount;
1732 for (int i = 0; i < N; i++) {
1733 if (mResId[i] != t.mResId[i] || mForce[i] != t.mForce[i]) {
1734 return false;
1735 }
1736 }
1737
1738 return true;
1739 }
1740
1741 /**
1742 * @return a shallow copy of this key
1743 */
1744 @Override
1745 public ThemeKey clone() {
1746 final ThemeKey other = new ThemeKey();
1747 other.mResId = mResId;
1748 other.mForce = mForce;
1749 other.mCount = mCount;
John Reck4feb3262015-07-13 14:42:43 -07001750 other.mHashCode = mHashCode;
Alan Viverettee54d2452015-05-06 10:41:43 -07001751 return other;
1752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 }
1754
1755 /**
1756 * Generate a new Theme object for this set of Resources. It initially
1757 * starts out empty.
Jon Miranda836c0a82014-08-11 12:32:26 -07001758 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 * @return Theme The newly created Theme container.
1760 */
1761 public final Theme newTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001762 Theme theme = new Theme();
1763 theme.setImpl(mResourcesImpl.newThemeImpl());
Adam Lesinski4fed9712017-05-23 13:14:54 -07001764 synchronized (mThemeRefs) {
1765 mThemeRefs.add(new WeakReference<>(theme));
1766 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001767 return theme;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 }
1769
1770 /**
1771 * Retrieve a set of basic attribute values from an AttributeSet, not
1772 * performing styling of them using a theme and/or style resources.
Jon Miranda836c0a82014-08-11 12:32:26 -07001773 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001774 * @param set The current attribute values to retrieve.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001775 * @param attrs The specific attributes to be retrieved. These attribute IDs must be sorted in
1776 * ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 * @return Returns a TypedArray holding an array of the attribute values.
1778 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1779 * when done with it.
1780 *
1781 * @see Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
1782 */
Adam Lesinski5ec88752017-04-12 14:45:14 -07001783 public TypedArray obtainAttributes(AttributeSet set, @StyleableRes int[] attrs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 int len = attrs.length;
Alan Viverette52b999f2014-03-24 18:00:26 -07001785 TypedArray array = TypedArray.obtain(this, len);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001786
1787 // XXX note that for now we only work with compiled XML files.
1788 // To support generic XML files we will need to manually parse
1789 // out the attributes from the XML file (applying type information
1790 // contained in the resources and such).
1791 XmlBlock.Parser parser = (XmlBlock.Parser)set;
Adam Lesinskidcb3c652017-01-23 12:58:11 -08001792 mResourcesImpl.getAssets().retrieveAttributes(parser, attrs, array.mData, array.mIndices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 array.mXml = parser;
1795
1796 return array;
1797 }
Mitsuru Oshimae5fb3282009-06-09 21:16:08 -07001798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 /**
1800 * Store the newly updated configuration.
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -07001801 *
1802 * @deprecated See {@link android.content.Context#createConfigurationContext(Configuration)}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 */
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -07001804 @Deprecated
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001805 public void updateConfiguration(Configuration config, DisplayMetrics metrics) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001806 updateConfiguration(config, metrics, null);
1807 }
1808
1809 /**
1810 * @hide
1811 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001812 public void updateConfiguration(Configuration config, DisplayMetrics metrics,
1813 CompatibilityInfo compat) {
1814 mResourcesImpl.updateConfiguration(config, metrics, compat);
Narayan Kamath21fc8ba2014-03-05 18:42:23 +00001815 }
1816
1817 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001818 * Update the system resources configuration if they have previously
1819 * been initialized.
1820 *
1821 * @hide
1822 */
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001823 public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics,
1824 CompatibilityInfo compat) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 if (mSystem != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001826 mSystem.updateConfiguration(config, metrics, compat);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 //Log.i(TAG, "Updated system resources " + mSystem
1828 // + ": " + mSystem.getConfiguration());
1829 }
1830 }
1831
1832 /**
1833 * Return the current display metrics that are in effect for this resource
1834 * object. The returned object should be treated as read-only.
1835 *
1836 * @return The resource's current display metrics.
1837 */
1838 public DisplayMetrics getDisplayMetrics() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001839 return mResourcesImpl.getDisplayMetrics();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 }
1841
Adam Lesinski4ece3d62016-06-16 18:05:41 -07001842 /** @hide */
1843 public DisplayAdjustments getDisplayAdjustments() {
1844 return mResourcesImpl.getDisplayAdjustments();
1845 }
1846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 /**
1848 * Return the current configuration that is in effect for this resource
1849 * object. The returned object should be treated as read-only.
1850 *
1851 * @return The resource's current configuration.
1852 */
1853 public Configuration getConfiguration() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001854 return mResourcesImpl.getConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 }
Filip Gruszczynski23493322015-07-29 17:02:59 -07001856
1857 /** @hide */
1858 public Configuration[] getSizeConfigurations() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001859 return mResourcesImpl.getSizeConfigurations();
1860 }
Filip Gruszczynski23493322015-07-29 17:02:59 -07001861
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07001862 /**
1863 * Return the compatibility mode information for the application.
1864 * The returned object should be treated as read-only.
1865 *
Dianne Hackborn3904d032011-05-27 12:09:11 -07001866 * @return compatibility info.
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07001867 * @hide
1868 */
1869 public CompatibilityInfo getCompatibilityInfo() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001870 return mResourcesImpl.getCompatibilityInfo();
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07001871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001872
1873 /**
Dianne Hackborna53b8282009-07-17 11:13:48 -07001874 * This is just for testing.
1875 * @hide
1876 */
Adam Lesinski082614c2016-03-04 14:33:47 -08001877 @VisibleForTesting
Dianne Hackborna53b8282009-07-17 11:13:48 -07001878 public void setCompatibilityInfo(CompatibilityInfo ci) {
Adam Lesinski79a8ffe2013-09-19 20:33:15 -07001879 if (ci != null) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001880 mResourcesImpl.updateConfiguration(null, null, ci);
Adam Lesinski79a8ffe2013-09-19 20:33:15 -07001881 }
Dianne Hackborna53b8282009-07-17 11:13:48 -07001882 }
1883
1884 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 * Return a resource identifier for the given resource name. A fully
1886 * qualified resource name is of the form "package:type/entry". The first
1887 * two components (package and type) are optional if defType and
1888 * defPackage, respectively, are specified here.
1889 *
1890 * <p>Note: use of this function is discouraged. It is much more
1891 * efficient to retrieve resources by identifier than by name.
1892 *
1893 * @param name The name of the desired resource.
1894 * @param defType Optional default resource type to find, if "type/" is
1895 * not included in the name. Can be null to require an
1896 * explicit type.
1897 * @param defPackage Optional default package to find, if "package:" is
1898 * not included in the name. Can be null to require an
1899 * explicit package.
1900 *
1901 * @return int The associated resource identifier. Returns 0 if no such
1902 * resource was found. (0 is not a valid resource ID.)
1903 */
1904 public int getIdentifier(String name, String defType, String defPackage) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001905 return mResourcesImpl.getIdentifier(name, defType, defPackage);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 }
1907
1908 /**
Jeff Sharkey47b50332013-03-15 14:46:46 -07001909 * Return true if given resource identifier includes a package.
1910 *
1911 * @hide
1912 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001913 public static boolean resourceHasPackage(@AnyRes int resid) {
Jeff Sharkey47b50332013-03-15 14:46:46 -07001914 return (resid >>> 24) != 0;
1915 }
1916
1917 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001918 * Return the full name for a given resource identifier. This name is
1919 * a single string of the form "package:type/entry".
1920 *
1921 * @param resid The resource identifier whose name is to be retrieved.
1922 *
1923 * @return A string holding the name of the resource.
1924 *
1925 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1926 *
1927 * @see #getResourcePackageName
1928 * @see #getResourceTypeName
1929 * @see #getResourceEntryName
1930 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001931 public String getResourceName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001932 return mResourcesImpl.getResourceName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001933 }
1934
1935 /**
1936 * Return the package name for a given resource identifier.
1937 *
1938 * @param resid The resource identifier whose package name is to be
1939 * retrieved.
1940 *
1941 * @return A string holding the package name of the resource.
1942 *
1943 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1944 *
1945 * @see #getResourceName
1946 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001947 public String getResourcePackageName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001948 return mResourcesImpl.getResourcePackageName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 }
1950
1951 /**
1952 * Return the type name for a given resource identifier.
1953 *
1954 * @param resid The resource identifier whose type name is to be
1955 * retrieved.
1956 *
1957 * @return A string holding the type name of the resource.
1958 *
1959 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1960 *
1961 * @see #getResourceName
1962 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001963 public String getResourceTypeName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001964 return mResourcesImpl.getResourceTypeName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001965 }
1966
1967 /**
1968 * Return the entry name for a given resource identifier.
1969 *
1970 * @param resid The resource identifier whose entry name is to be
1971 * retrieved.
1972 *
1973 * @return A string holding the entry name of the resource.
1974 *
1975 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1976 *
1977 * @see #getResourceName
1978 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001979 public String getResourceEntryName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001980 return mResourcesImpl.getResourceEntryName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 }
1982
1983 /**
1984 * Parse a series of {@link android.R.styleable#Extra &lt;extra&gt;} tags from
1985 * an XML file. You call this when you are at the parent tag of the
Dianne Hackborndef15372010-08-15 12:43:52 -07001986 * extra tags, and it will return once all of the child tags have been parsed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 * This will call {@link #parseBundleExtra} for each extra tag encountered.
1988 *
1989 * @param parser The parser from which to retrieve the extras.
1990 * @param outBundle A Bundle in which to place all parsed extras.
1991 * @throws XmlPullParserException
1992 * @throws IOException
1993 */
1994 public void parseBundleExtras(XmlResourceParser parser, Bundle outBundle)
1995 throws XmlPullParserException, IOException {
1996 int outerDepth = parser.getDepth();
1997 int type;
1998 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1999 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2000 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2001 continue;
2002 }
2003
2004 String nodeName = parser.getName();
2005 if (nodeName.equals("extra")) {
2006 parseBundleExtra("extra", parser, outBundle);
2007 XmlUtils.skipCurrentTag(parser);
2008
2009 } else {
2010 XmlUtils.skipCurrentTag(parser);
2011 }
2012 }
2013 }
2014
2015 /**
2016 * Parse a name/value pair out of an XML tag holding that data. The
2017 * AttributeSet must be holding the data defined by
2018 * {@link android.R.styleable#Extra}. The following value types are supported:
2019 * <ul>
2020 * <li> {@link TypedValue#TYPE_STRING}:
2021 * {@link Bundle#putCharSequence Bundle.putCharSequence()}
2022 * <li> {@link TypedValue#TYPE_INT_BOOLEAN}:
2023 * {@link Bundle#putCharSequence Bundle.putBoolean()}
2024 * <li> {@link TypedValue#TYPE_FIRST_INT}-{@link TypedValue#TYPE_LAST_INT}:
2025 * {@link Bundle#putCharSequence Bundle.putBoolean()}
2026 * <li> {@link TypedValue#TYPE_FLOAT}:
2027 * {@link Bundle#putCharSequence Bundle.putFloat()}
2028 * </ul>
2029 *
2030 * @param tagName The name of the tag these attributes come from; this is
2031 * only used for reporting error messages.
2032 * @param attrs The attributes from which to retrieve the name/value pair.
2033 * @param outBundle The Bundle in which to place the parsed value.
2034 * @throws XmlPullParserException If the attributes are not valid.
2035 */
2036 public void parseBundleExtra(String tagName, AttributeSet attrs,
2037 Bundle outBundle) throws XmlPullParserException {
2038 TypedArray sa = obtainAttributes(attrs,
2039 com.android.internal.R.styleable.Extra);
2040
2041 String name = sa.getString(
2042 com.android.internal.R.styleable.Extra_name);
2043 if (name == null) {
2044 sa.recycle();
2045 throw new XmlPullParserException("<" + tagName
2046 + "> requires an android:name attribute at "
2047 + attrs.getPositionDescription());
2048 }
2049
2050 TypedValue v = sa.peekValue(
2051 com.android.internal.R.styleable.Extra_value);
2052 if (v != null) {
2053 if (v.type == TypedValue.TYPE_STRING) {
2054 CharSequence cs = v.coerceToString();
2055 outBundle.putCharSequence(name, cs);
2056 } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
2057 outBundle.putBoolean(name, v.data != 0);
2058 } else if (v.type >= TypedValue.TYPE_FIRST_INT
2059 && v.type <= TypedValue.TYPE_LAST_INT) {
2060 outBundle.putInt(name, v.data);
2061 } else if (v.type == TypedValue.TYPE_FLOAT) {
2062 outBundle.putFloat(name, v.getFloat());
2063 } else {
2064 sa.recycle();
2065 throw new XmlPullParserException("<" + tagName
2066 + "> only supports string, integer, float, color, and boolean at "
2067 + attrs.getPositionDescription());
2068 }
2069 } else {
2070 sa.recycle();
2071 throw new XmlPullParserException("<" + tagName
2072 + "> requires an android:value or android:resource attribute at "
2073 + attrs.getPositionDescription());
2074 }
2075
2076 sa.recycle();
2077 }
2078
2079 /**
2080 * Retrieve underlying AssetManager storage for these resources.
2081 */
2082 public final AssetManager getAssets() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002083 return mResourcesImpl.getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002084 }
2085
2086 /**
2087 * Call this to remove all cached loaded layout resources from the
2088 * Resources object. Only intended for use with performance testing
2089 * tools.
2090 */
2091 public final void flushLayoutCache() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002092 mResourcesImpl.flushLayoutCache();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
2094
2095 /**
2096 * Start preloading of resource data using this Resources object. Only
2097 * for use by the zygote process for loading common system resources.
2098 * {@hide}
2099 */
2100 public final void startPreloading() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002101 mResourcesImpl.startPreloading();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 }
2103
2104 /**
2105 * Called by zygote when it is done preloading resources, to change back
2106 * to normal Resources operation.
2107 */
2108 public final void finishPreloading() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002109 mResourcesImpl.finishPreloading();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002110 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07002111
Romain Guy3b748a42013-04-17 18:54:38 -07002112 /**
2113 * @hide
2114 */
Alan Viverette52b999f2014-03-24 18:00:26 -07002115 public LongSparseArray<ConstantState> getPreloadedDrawables() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002116 return mResourcesImpl.getPreloadedDrawables();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 }
2118
Alan Viverette10979612016-01-06 15:27:35 -05002119 /**
2120 * Loads an XML parser for the specified file.
2121 *
2122 * @param id the resource identifier for the file
2123 * @param type the type of resource (used for logging)
2124 * @return a parser for the specified XML file
2125 * @throws NotFoundException if the file could not be loaded
2126 */
2127 @NonNull
2128 XmlResourceParser loadXmlResourceParser(@AnyRes int id, @NonNull String type)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002130 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05002131 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002132 final ResourcesImpl impl = mResourcesImpl;
2133 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002134 if (value.type == TypedValue.TYPE_STRING) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002135 return impl.loadXmlResourceParser(value.string.toString(), id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 value.assetCookie, type);
2137 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05002138 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
2139 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
2140 } finally {
2141 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 }
2143 }
Alan Viverette10979612016-01-06 15:27:35 -05002144
2145 /**
2146 * Loads an XML parser for the specified file.
2147 *
2148 * @param file the path for the XML file to parse
2149 * @param id the resource identifier for the file
2150 * @param assetCookie the asset cookie for the file
2151 * @param type the type of resource (used for logging)
2152 * @return a parser for the specified XML file
2153 * @throws NotFoundException if the file could not be loaded
2154 */
2155 @NonNull
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002156 XmlResourceParser loadXmlResourceParser(String file, int id, int assetCookie,
2157 String type) throws NotFoundException {
2158 return mResourcesImpl.loadXmlResourceParser(file, id, assetCookie, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 }
2160
Alan Viverette45c4bbb2015-01-05 14:59:19 -08002161 /**
Adam Lesinski082614c2016-03-04 14:33:47 -08002162 * Called by ConfigurationBoundResourceCacheTest.
2163 * @hide
2164 */
2165 @VisibleForTesting
2166 public int calcConfigChanges(Configuration config) {
2167 return mResourcesImpl.calcConfigChanges(config);
2168 }
2169
2170 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -08002171 * Obtains styled attributes from the theme, if available, or unstyled
2172 * resources if the theme is null.
2173 *
2174 * @hide
2175 */
2176 public static TypedArray obtainAttributes(
2177 Resources res, Theme theme, AttributeSet set, int[] attrs) {
2178 if (theme == null) {
2179 return res.obtainAttributes(set, attrs);
2180 }
2181 return theme.obtainStyledAttributes(set, attrs, 0, 0);
2182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183}