blob: c698267b956bc7f44dd795ef402af39093fa5ca6 [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;
Winson9947f1e2019-08-16 10:20:39 -070033import android.annotation.IntRange;
Tor Norbye7b9c9122013-05-30 16:48:33 -070034import android.annotation.IntegerRes;
35import android.annotation.LayoutRes;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080036import android.annotation.NonNull;
Alan Viverette3b5c4272014-05-20 13:20:42 -070037import android.annotation.Nullable;
Tor Norbye7b9c9122013-05-30 16:48:33 -070038import android.annotation.PluralsRes;
39import android.annotation.RawRes;
40import android.annotation.StringRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070041import android.annotation.StyleRes;
42import android.annotation.StyleableRes;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010043import android.annotation.UnsupportedAppUsage;
Tor Norbye7b9c9122013-05-30 16:48:33 -070044import android.annotation.XmlRes;
Winson9947f1e2019-08-16 10:20:39 -070045import android.app.ResourcesManager;
Dianne Hackbornebff8f92011-05-12 18:07:47 -070046import android.content.pm.ActivityInfo;
Alan Viverette9ad386b2017-01-26 14:00:20 -050047import android.content.pm.ActivityInfo.Config;
Winson9947f1e2019-08-16 10:20:39 -070048import android.content.res.loader.ResourceLoader;
49import android.content.res.loader.ResourceLoaderManager;
50import android.content.res.loader.ResourcesProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.graphics.Movie;
Clara Bayarri18e9f9f2016-12-19 16:20:29 +000052import android.graphics.Typeface;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080053import android.graphics.drawable.Drawable;
Masanori Oginoc7d9d272010-07-10 12:10:41 +090054import android.graphics.drawable.Drawable.ConstantState;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070055import android.graphics.drawable.DrawableInflater;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070056import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.util.AttributeSet;
59import android.util.DisplayMetrics;
60import android.util.Log;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080061import android.util.LongSparseArray;
Winson9947f1e2019-08-16 10:20:39 -070062import android.util.Pair;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080063import android.util.Pools.SynchronizedPool;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.util.TypedValue;
Adam Lesinski4ece3d62016-06-16 18:05:41 -070065import android.view.DisplayAdjustments;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080066import android.view.ViewDebug;
Siva Velusamy0d857b92015-04-22 10:23:56 -070067import android.view.ViewHierarchyEncoder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
Winson9947f1e2019-08-16 10:20:39 -070069import com.android.internal.annotations.GuardedBy;
Adam Lesinski082614c2016-03-04 14:33:47 -080070import com.android.internal.annotations.VisibleForTesting;
Winson9947f1e2019-08-16 10:20:39 -070071import com.android.internal.util.ArrayUtils;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070072import com.android.internal.util.GrowingArrayUtils;
73import com.android.internal.util.XmlUtils;
74
75import org.xmlpull.v1.XmlPullParser;
76import org.xmlpull.v1.XmlPullParserException;
77
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import java.io.IOException;
79import java.io.InputStream;
Adam Lesinski082614c2016-03-04 14:33:47 -080080import java.lang.ref.WeakReference;
81import java.util.ArrayList;
Winson9947f1e2019-08-16 10:20:39 -070082import java.util.Collections;
83import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084
85/**
86 * Class for accessing an application's resources. This sits on top of the
Scott Mainf4f05b82011-01-07 14:38:23 -080087 * asset manager of the application (accessible through {@link #getAssets}) and
88 * provides a high-level API for getting typed data from the assets.
89 *
90 * <p>The Android resource system keeps track of all non-code assets associated with an
91 * application. You can use this class to access your application's resources. You can generally
92 * acquire the {@link android.content.res.Resources} instance associated with your application
93 * with {@link android.content.Context#getResources getResources()}.</p>
94 *
95 * <p>The Android SDK tools compile your application's resources into the application binary
96 * at build time. To use a resource, you must install it correctly in the source tree (inside
97 * your project's {@code res/} directory) and build your application. As part of the build
98 * process, the SDK tools generate symbols for each resource, which you can use in your application
99 * code to access the resources.</p>
100 *
101 * <p>Using application resources makes it easy to update various characteristics of your
102 * application without modifying code, and&mdash;by providing sets of alternative
103 * resources&mdash;enables you to optimize your application for a variety of device configurations
104 * (such as for different languages and screen sizes). This is an important aspect of developing
105 * Android applications that are compatible on different types of devices.</p>
106 *
107 * <p>For more information about using resources, see the documentation about <a
108 * href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 */
110public class Resources {
Aurimas Liutikas83386232019-01-16 12:46:42 -0800111 /**
112 * The {@code null} resource ID. This denotes an invalid resource ID that is returned by the
113 * system when a resource is not found or the value is set to {@code @null} in XML.
114 */
115 public static final @AnyRes int ID_NULL = 0;
116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 static final String TAG = "Resources";
Alan Viverette562a6a82014-01-31 11:07:29 -0800118
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800119 private static final Object sSync = new Object();
Fabrice Di Megliob9a13b82013-04-15 14:05:30 -0700120
Alan Viveretteedc46642014-02-01 01:43:16 -0800121 // Used by BridgeResources in layoutlib
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100122 @UnsupportedAppUsage
Alan Viveretteedc46642014-02-01 01:43:16 -0800123 static Resources mSystem = null;
124
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100125 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800126 private ResourcesImpl mResourcesImpl;
Alan Viverette4d07bc92015-11-16 10:19:12 -0500127
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800128 // Pool of TypedArrays targeted to this Resources object.
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100129 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800130 final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400132 /** Used to inflate drawable objects from XML. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100133 @UnsupportedAppUsage
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400134 private DrawableInflater mDrawableInflater;
135
Alan Viverette4d07bc92015-11-16 10:19:12 -0500136 /** Lock object used to protect access to {@link #mTmpValue}. */
137 private final Object mTmpValueLock = new Object();
138
139 /** Single-item pool used to minimize TypedValue allocations. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100140 @UnsupportedAppUsage
Alan Viverette562a6a82014-01-31 11:07:29 -0800141 private TypedValue mTmpValue = new TypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500142
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100143 @UnsupportedAppUsage
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400144 final ClassLoader mClassLoader;
Fabrice Di Megliob9a13b82013-04-15 14:05:30 -0700145
Winson9947f1e2019-08-16 10:20:39 -0700146 private final Object mResourceLoaderLock = new Object();
147
148 @GuardedBy("mResourceLoaderLock")
149 private ResourceLoaderManager mResourceLoaderManager;
150
Alan Viverette62599332014-04-01 14:57:39 -0700151 /**
Adam Lesinski082614c2016-03-04 14:33:47 -0800152 * WeakReferences to Themes that were constructed from this Resources object.
153 * We keep track of these in case our underlying implementation is changed, in which case
154 * the Themes must also get updated ThemeImpls.
155 */
156 private final ArrayList<WeakReference<Theme>> mThemeRefs = new ArrayList<>();
157
158 /**
Richard Uhlerdd6a0db2018-04-26 15:09:30 +0100159 * To avoid leaking WeakReferences to garbage collected Themes on the
160 * mThemeRefs list, we flush the list of stale references any time the
161 * mThemeRefNextFlushSize is reached.
162 */
163 private static final int MIN_THEME_REFS_FLUSH_SIZE = 32;
164 private int mThemeRefsNextFlushSize = MIN_THEME_REFS_FLUSH_SIZE;
165
Winson9947f1e2019-08-16 10:20:39 -0700166 private int mBaseApkAssetsSize;
167
Richard Uhlerdd6a0db2018-04-26 15:09:30 +0100168 /**
Alan Viverette62599332014-04-01 14:57:39 -0700169 * Returns the most appropriate default theme for the specified target SDK version.
Alan Viverette5effd7e2014-05-05 12:25:33 -0700170 * <ul>
171 * <li>Below API 11: Gingerbread
Alan Viverette4b2b6152016-06-08 11:45:15 -0400172 * <li>APIs 12 thru 14: Holo
173 * <li>APIs 15 thru 23: Device default dark
174 * <li>APIs 24 and above: Device default light with dark action bar
Alan Viverette5effd7e2014-05-05 12:25:33 -0700175 * </ul>
Alan Viverette62599332014-04-01 14:57:39 -0700176 *
177 * @param curTheme The current theme, or 0 if not specified.
178 * @param targetSdkVersion The target SDK version.
179 * @return A theme resource identifier
180 * @hide
181 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100182 @UnsupportedAppUsage
Alan Viverette5effd7e2014-05-05 12:25:33 -0700183 public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800184 return selectSystemTheme(curTheme, targetSdkVersion,
Alan Viverette5effd7e2014-05-05 12:25:33 -0700185 com.android.internal.R.style.Theme,
186 com.android.internal.R.style.Theme_Holo,
187 com.android.internal.R.style.Theme_DeviceDefault,
188 com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800189 }
Alan Viverette62599332014-04-01 14:57:39 -0700190
Alan Viverette5effd7e2014-05-05 12:25:33 -0700191 /** @hide */
192 public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo,
193 int dark, int deviceDefault) {
Aurimas Liutikasd8ebfef2019-01-16 12:46:42 -0800194 if (curTheme != ID_NULL) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800195 return curTheme;
196 }
Alan Viverette5effd7e2014-05-05 12:25:33 -0700197 if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
198 return orig;
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800199 }
Alan Viverette5effd7e2014-05-05 12:25:33 -0700200 if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
201 return holo;
202 }
Alan Viverette4b2b6152016-06-08 11:45:15 -0400203 if (targetSdkVersion < Build.VERSION_CODES.N) {
Alan Viverette5effd7e2014-05-05 12:25:33 -0700204 return dark;
205 }
206 return deviceDefault;
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800207 }
Alan Viverette62599332014-04-01 14:57:39 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800210 * Return a global shared Resources object that provides access to only
MÃ¥rten Kongstad371da732019-03-13 22:27:40 +0100211 * system resources (no application resources), is not configured for the
212 * current screen (can not use dimension units, does not change based on
213 * orientation, etc), and is not affected by Runtime Resource Overlay.
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400214 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800215 public static Resources getSystem() {
216 synchronized (sSync) {
217 Resources ret = mSystem;
218 if (ret == null) {
219 ret = new Resources();
220 mSystem = ret;
221 }
222 return ret;
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400223 }
Yigit Boyard422dc32014-09-25 12:23:35 -0700224 }
225
226 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 * This exception is thrown by the resource APIs when a requested resource
228 * can not be found.
229 */
230 public static class NotFoundException extends RuntimeException {
231 public NotFoundException() {
232 }
233
234 public NotFoundException(String name) {
235 super(name);
236 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500237
238 public NotFoundException(String name, Exception cause) {
239 super(name, cause);
240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 }
242
243 /**
244 * Create a new Resources object on top of an existing set of assets in an
245 * AssetManager.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800246 *
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -0700247 * @deprecated Resources should not be constructed by apps.
248 * See {@link android.content.Context#createConfigurationContext(Configuration)}.
249 *
Wale Ogunwale60454db2015-01-23 16:05:07 -0800250 * @param assets Previously created AssetManager.
251 * @param metrics Current display metrics to consider when
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 * selecting/computing resource values.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800253 * @param config Desired device configuration to consider when
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 * selecting/computing resource values (optional).
255 */
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -0700256 @Deprecated
Romain Guy5d911c32012-04-12 16:25:17 -0700257 public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800258 this(null);
Adam Lesinski8e8d2322016-06-24 12:29:16 -0700259 mResourcesImpl = new ResourcesImpl(assets, metrics, config, new DisplayAdjustments());
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700260 }
261
262 /**
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -0700263 * Creates a new Resources object with CompatibilityInfo.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800264 *
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400265 * @param classLoader class loader for the package used to load custom
266 * resource classes, may be {@code null} to use system
267 * class loader
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700268 * @hide
269 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100270 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800271 public Resources(@Nullable ClassLoader classLoader) {
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400272 mClassLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader;
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700273 }
274
275 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800276 * Only for creating the System resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100278 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800279 private Resources() {
280 this(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800282 final DisplayMetrics metrics = new DisplayMetrics();
283 metrics.setToDefaults();
284
285 final Configuration config = new Configuration();
286 config.setToDefaults();
287
288 mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
Adam Lesinski8e8d2322016-06-24 12:29:16 -0700289 new DisplayAdjustments());
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800290 }
291
292 /**
Adam Lesinski082614c2016-03-04 14:33:47 -0800293 * Set the underlying implementation (containing all the resources and caches)
294 * and updates all Theme references to new implementations as well.
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800295 * @hide
296 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100297 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800298 public void setImpl(ResourcesImpl impl) {
Adam Lesinski082614c2016-03-04 14:33:47 -0800299 if (impl == mResourcesImpl) {
300 return;
301 }
302
Winson9947f1e2019-08-16 10:20:39 -0700303 mBaseApkAssetsSize = ArrayUtils.size(impl.getAssets().getApkAssets());
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800304 mResourcesImpl = impl;
Adam Lesinski082614c2016-03-04 14:33:47 -0800305
Winson9947f1e2019-08-16 10:20:39 -0700306 synchronized (mResourceLoaderLock) {
307 if (mResourceLoaderManager != null) {
308 mResourceLoaderManager.onImplUpdate(mResourcesImpl);
309 }
310 }
311
Adam Lesinski082614c2016-03-04 14:33:47 -0800312 // Create new ThemeImpls that are identical to the ones we have.
313 synchronized (mThemeRefs) {
314 final int count = mThemeRefs.size();
315 for (int i = 0; i < count; i++) {
316 WeakReference<Theme> weakThemeRef = mThemeRefs.get(i);
317 Theme theme = weakThemeRef != null ? weakThemeRef.get() : null;
318 if (theme != null) {
319 theme.setImpl(mResourcesImpl.newThemeImpl(theme.getKey()));
320 }
321 }
322 }
323 }
324
325 /**
326 * @hide
327 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100328 @UnsupportedAppUsage
Adam Lesinski082614c2016-03-04 14:33:47 -0800329 public ResourcesImpl getImpl() {
330 return mResourcesImpl;
331 }
332
333 /**
334 * @hide
335 */
336 public ClassLoader getClassLoader() {
337 return mClassLoader;
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800338 }
339
340 /**
341 * @return the inflater used to create drawable objects
342 * @hide Pending API finalization.
343 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100344 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800345 public final DrawableInflater getDrawableInflater() {
346 if (mDrawableInflater == null) {
347 mDrawableInflater = new DrawableInflater(this, mClassLoader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800349 return mDrawableInflater;
350 }
351
352 /**
353 * Used by AnimatorInflater.
354 *
355 * @hide
356 */
357 public ConfigurationBoundResourceCache<Animator> getAnimatorCache() {
358 return mResourcesImpl.getAnimatorCache();
359 }
360
361 /**
362 * Used by AnimatorInflater.
363 *
364 * @hide
365 */
366 public ConfigurationBoundResourceCache<StateListAnimator> getStateListAnimatorCache() {
367 return mResourcesImpl.getStateListAnimatorCache();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 }
369
370 /**
371 * Return the string value associated with a particular resource ID. The
372 * returned object will be a String if this is a plain string; it will be
373 * some other type of CharSequence if it is styled.
374 * {@more}
375 *
376 * @param id The desired resource identifier, as generated by the aapt
377 * tool. This integer encodes the package, type, and resource
378 * entry. The value 0 is an invalid identifier.
379 *
380 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
381 *
382 * @return CharSequence The string data associated with the resource, plus
383 * possibly styled text information.
384 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800385 @NonNull public CharSequence getText(@StringRes int id) throws NotFoundException {
386 CharSequence res = mResourcesImpl.getAssets().getResourceText(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 if (res != null) {
388 return res;
389 }
390 throw new NotFoundException("String resource ID #0x"
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000391 + Integer.toHexString(id));
392 }
393
394 /**
395 * Return the Typeface value associated with a particular resource ID.
396 * {@more}
397 *
398 * @param id The desired resource identifier, as generated by the aapt
399 * tool. This integer encodes the package, type, and resource
400 * entry. The value 0 is an invalid identifier.
401 *
402 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
403 *
404 * @return Typeface The Typeface data associated with the resource.
405 */
Clara Bayarried00bfd2017-01-20 14:58:21 +0000406 @NonNull public Typeface getFont(@FontRes int id) throws NotFoundException {
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000407 final TypedValue value = obtainTempTypedValue();
408 try {
409 final ResourcesImpl impl = mResourcesImpl;
410 impl.getValue(id, value, true);
Clara Bayarried00bfd2017-01-20 14:58:21 +0000411 Typeface typeface = impl.loadFont(this, value, id);
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000412 if (typeface != null) {
413 return typeface;
414 }
415 } finally {
416 releaseTempTypedValue(value);
417 }
418 throw new NotFoundException("Font resource ID #0x"
419 + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
421
Clara Bayarried00bfd2017-01-20 14:58:21 +0000422 @NonNull
423 Typeface getFont(@NonNull TypedValue value, @FontRes int id) throws NotFoundException {
424 return mResourcesImpl.loadFont(this, value, id);
425 }
426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 /**
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000428 * @hide
429 */
Clara Bayarri2821eea2017-03-17 17:38:50 +0000430 public void preloadFonts(@ArrayRes int id) {
431 final TypedArray array = obtainTypedArray(id);
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000432 try {
Clara Bayarri2821eea2017-03-17 17:38:50 +0000433 final int size = array.length();
434 for (int i = 0; i < size; i++) {
435 array.getFont(i);
436 }
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000437 } finally {
Clara Bayarri2821eea2017-03-17 17:38:50 +0000438 array.recycle();
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000439 }
440 }
441
442 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800443 * Returns the character sequence necessary for grammatically correct pluralization
444 * of the given resource ID for the given quantity.
445 * Note that the character sequence is selected based solely on grammatical necessity,
446 * and that such rules differ between languages. Do not assume you know which string
447 * will be returned for a given quantity. See
448 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
449 * for more detail.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700450 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 * @param id The desired resource identifier, as generated by the aapt
452 * tool. This integer encodes the package, type, and resource
453 * entry. The value 0 is an invalid identifier.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700454 * @param quantity The number used to get the correct string for the current language's
455 * plural rules.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 *
457 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
458 *
459 * @return CharSequence The string data associated with the resource, plus
460 * possibly styled text information.
461 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800462 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700463 public CharSequence getQuantityText(@PluralsRes int id, int quantity)
464 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800465 return mResourcesImpl.getQuantityText(id, quantity);
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700466 }
467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 /**
469 * Return the string value associated with a particular resource ID. It
470 * will be stripped of any styled text information.
471 * {@more}
472 *
473 * @param id The desired resource identifier, as generated by the aapt
474 * tool. This integer encodes the package, type, and resource
475 * entry. The value 0 is an invalid identifier.
476 *
477 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
478 *
479 * @return String The string data associated with the resource,
Alan Viveretteb4004df2015-04-29 16:55:42 -0700480 * stripped of styled text information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 */
Alan Viveretteb4004df2015-04-29 16:55:42 -0700482 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700483 public String getString(@StringRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800484 return getText(id).toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 }
486
487
488 /**
489 * Return the string value associated with a particular resource ID,
490 * substituting the format arguments as defined in {@link java.util.Formatter}
491 * and {@link java.lang.String#format}. It will be stripped of any styled text
492 * information.
493 * {@more}
494 *
495 * @param id The desired resource identifier, as generated by the aapt
496 * tool. This integer encodes the package, type, and resource
497 * entry. The value 0 is an invalid identifier.
498 *
499 * @param formatArgs The format arguments that will be used for substitution.
500 *
501 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
502 *
503 * @return String The string data associated with the resource,
Alan Viveretteb4004df2015-04-29 16:55:42 -0700504 * stripped of styled text information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 */
Alan Viveretteb4004df2015-04-29 16:55:42 -0700506 @NonNull
507 public String getString(@StringRes int id, Object... formatArgs) throws NotFoundException {
508 final String raw = getString(id);
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800509 return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
510 formatArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 }
512
513 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800514 * Formats the string necessary for grammatically correct pluralization
515 * of the given resource ID for the given quantity, using the given arguments.
516 * Note that the string is selected based solely on grammatical necessity,
517 * and that such rules differ between languages. Do not assume you know which string
518 * will be returned for a given quantity. See
519 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
520 * for more detail.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 *
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800522 * <p>Substitution of format arguments works as if using
523 * {@link java.util.Formatter} and {@link java.lang.String#format}.
524 * The resulting string will be stripped of any styled text information.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700525 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 * @param id The desired resource identifier, as generated by the aapt
527 * tool. This integer encodes the package, type, and resource
528 * entry. The value 0 is an invalid identifier.
529 * @param quantity The number used to get the correct string for the current language's
530 * plural rules.
531 * @param formatArgs The format arguments that will be used for substitution.
532 *
533 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
534 *
535 * @return String The string data associated with the resource,
536 * stripped of styled text information.
537 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800538 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700539 public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 throws NotFoundException {
541 String raw = getQuantityText(id, quantity).toString();
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800542 return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
543 formatArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 }
545
546 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800547 * Returns the string necessary for grammatically correct pluralization
548 * of the given resource ID for the given quantity.
549 * Note that the string is selected based solely on grammatical necessity,
550 * and that such rules differ between languages. Do not assume you know which string
551 * will be returned for a given quantity. See
552 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
553 * for more detail.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700554 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 * @param id The desired resource identifier, as generated by the aapt
556 * tool. This integer encodes the package, type, and resource
557 * entry. The value 0 is an invalid identifier.
558 * @param quantity The number used to get the correct string for the current language's
559 * plural rules.
560 *
561 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
562 *
563 * @return String The string data associated with the resource,
564 * stripped of styled text information.
565 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800566 @NonNull
567 public String getQuantityString(@PluralsRes int id, int quantity) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 return getQuantityText(id, quantity).toString();
569 }
570
571 /**
572 * Return the string value associated with a particular resource ID. The
573 * returned object will be a String if this is a plain string; it will be
574 * some other type of CharSequence if it is styled.
575 *
576 * @param id The desired resource identifier, as generated by the aapt
577 * tool. This integer encodes the package, type, and resource
578 * entry. The value 0 is an invalid identifier.
579 *
580 * @param def The default CharSequence to return.
581 *
582 * @return CharSequence The string data associated with the resource, plus
583 * possibly styled text information, or def if id is 0 or not found.
584 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700585 public CharSequence getText(@StringRes int id, CharSequence def) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800586 CharSequence res = id != 0 ? mResourcesImpl.getAssets().getResourceText(id) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 return res != null ? res : def;
588 }
589
590 /**
591 * Return the styled text array associated with a particular resource ID.
592 *
593 * @param id The desired resource identifier, as generated by the aapt
594 * tool. This integer encodes the package, type, and resource
595 * entry. The value 0 is an invalid identifier.
596 *
597 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
598 *
599 * @return The styled text array associated with the resource.
600 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800601 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700602 public CharSequence[] getTextArray(@ArrayRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800603 CharSequence[] res = mResourcesImpl.getAssets().getResourceTextArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 if (res != null) {
605 return res;
606 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800607 throw new NotFoundException("Text array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 }
609
610 /**
611 * Return the string array associated with a particular resource ID.
612 *
613 * @param id The desired resource identifier, as generated by the aapt
614 * tool. This integer encodes the package, type, and resource
615 * entry. The value 0 is an invalid identifier.
616 *
617 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
618 *
619 * @return The string array associated with the resource.
620 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800621 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700622 public String[] getStringArray(@ArrayRes int id)
623 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800624 String[] res = mResourcesImpl.getAssets().getResourceStringArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 if (res != null) {
626 return res;
627 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800628 throw new NotFoundException("String array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 }
630
631 /**
632 * Return the int array associated with a particular resource ID.
633 *
634 * @param id The desired resource identifier, as generated by the aapt
635 * tool. This integer encodes the package, type, and resource
636 * entry. The value 0 is an invalid identifier.
637 *
638 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
639 *
640 * @return The int array associated with the resource.
641 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800642 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700643 public int[] getIntArray(@ArrayRes int id) throws NotFoundException {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800644 int[] res = mResourcesImpl.getAssets().getResourceIntArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 if (res != null) {
646 return res;
647 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800648 throw new NotFoundException("Int array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 }
650
651 /**
652 * Return an array of heterogeneous values.
653 *
654 * @param id The desired resource identifier, as generated by the aapt
655 * tool. This integer encodes the package, type, and resource
656 * entry. The value 0 is an invalid identifier.
657 *
658 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
659 *
660 * @return Returns a TypedArray holding an array of the array values.
661 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
662 * when done with it.
663 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800664 @NonNull
665 public TypedArray obtainTypedArray(@ArrayRes int id) throws NotFoundException {
666 final ResourcesImpl impl = mResourcesImpl;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800667 int len = impl.getAssets().getResourceArraySize(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 if (len < 0) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800669 throw new NotFoundException("Array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 }
671
Alan Viverette52b999f2014-03-24 18:00:26 -0700672 TypedArray array = TypedArray.obtain(this, len);
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800673 array.mLength = impl.getAssets().getResourceArray(id, array.mData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 array.mIndices[0] = 0;
675
676 return array;
677 }
678
679 /**
680 * Retrieve a dimensional for a particular resource ID. Unit
681 * conversions are based on the current {@link DisplayMetrics} associated
682 * with the resources.
683 *
684 * @param id The desired resource identifier, as generated by the aapt
685 * tool. This integer encodes the package, type, and resource
686 * entry. The value 0 is an invalid identifier.
687 *
Danny Epstein4ffbd472018-06-29 16:21:03 -0700688 * @return Resource dimension value multiplied by the appropriate metric to convert to pixels.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 *
690 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
691 *
692 * @see #getDimensionPixelOffset
693 * @see #getDimensionPixelSize
694 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700695 public float getDimension(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800696 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500697 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800698 final ResourcesImpl impl = mResourcesImpl;
699 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800701 return TypedValue.complexToDimension(value.data, impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500703 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
704 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
705 } finally {
706 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 }
708 }
709
710 /**
711 * Retrieve a dimensional for a particular resource ID for use
712 * as an offset in raw pixels. This is the same as
713 * {@link #getDimension}, except the returned value is converted to
714 * integer pixels for you. An offset conversion involves simply
715 * truncating the base value to an integer.
716 *
717 * @param id The desired resource identifier, as generated by the aapt
718 * tool. This integer encodes the package, type, and resource
719 * entry. The value 0 is an invalid identifier.
720 *
721 * @return Resource dimension value multiplied by the appropriate
722 * metric and truncated to integer pixels.
723 *
724 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
725 *
726 * @see #getDimension
727 * @see #getDimensionPixelSize
728 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700729 public int getDimensionPixelOffset(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800730 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500731 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800732 final ResourcesImpl impl = mResourcesImpl;
733 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800735 return TypedValue.complexToDimensionPixelOffset(value.data,
736 impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500738 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
739 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
740 } finally {
741 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 }
743 }
744
745 /**
746 * Retrieve a dimensional for a particular resource ID for use
747 * as a size in raw pixels. This is the same as
748 * {@link #getDimension}, except the returned value is converted to
749 * integer pixels for use as a size. A size conversion involves
750 * rounding the base value, and ensuring that a non-zero base value
751 * is at least one pixel in size.
752 *
753 * @param id The desired resource identifier, as generated by the aapt
754 * tool. This integer encodes the package, type, and resource
755 * entry. The value 0 is an invalid identifier.
756 *
757 * @return Resource dimension value multiplied by the appropriate
758 * metric and truncated to integer pixels.
759 *
760 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
761 *
762 * @see #getDimension
763 * @see #getDimensionPixelOffset
764 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700765 public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800766 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500767 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800768 final ResourcesImpl impl = mResourcesImpl;
769 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800771 return TypedValue.complexToDimensionPixelSize(value.data, impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500773 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
774 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
775 } finally {
776 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 }
778 }
779
780 /**
781 * Retrieve a fractional unit for a particular resource ID.
782 *
783 * @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.
786 * @param base The base value of this fraction. In other words, a
787 * standard fraction is multiplied by this value.
788 * @param pbase The parent base value of this fraction. In other
789 * words, a parent fraction (nn%p) is multiplied by this
790 * value.
791 *
792 * @return Attribute fractional value multiplied by the appropriate
793 * base value.
794 *
795 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
796 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700797 public float getFraction(@FractionRes int id, int base, int pbase) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800798 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500799 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800800 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 if (value.type == TypedValue.TYPE_FRACTION) {
802 return TypedValue.complexToFraction(value.data, base, pbase);
803 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500804 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
805 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
806 } finally {
807 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 }
809 }
810
811 /**
812 * Return a drawable object associated with a particular resource ID.
813 * Various types of objects will be returned depending on the underlying
814 * resource -- for example, a solid color, PNG image, scalable image, etc.
815 * The Drawable API hides these implementation details.
Dianne Hackbornfb5c3db2012-05-18 15:24:24 -0700816 *
817 * <p class="note"><strong>Note:</strong> Prior to
818 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN}, this function
819 * would not correctly retrieve the final configuration density when
820 * the resource ID passed here is an alias to another Drawable resource.
821 * This means that if the density configuration of the alias resource
822 * is different than the actual resource, the density of the returned
Alan Viverette952802e2016-04-04 15:33:41 -0400823 * Drawable would be incorrect, resulting in bad scaling. To work
824 * around this, you can instead manually resolve the aliased reference
825 * by using {@link #getValue(int, TypedValue, boolean)} and passing
826 * {@code true} for {@code resolveRefs}. The resulting
827 * {@link TypedValue#resourceId} value may be passed to this method.</p>
Dianne Hackbornfb5c3db2012-05-18 15:24:24 -0700828 *
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700829 * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use
830 * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)}
831 * or {@link #getDrawable(int, Theme)} passing the desired theme.</p>
832 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 * @param id The desired resource identifier, as generated by the aapt
834 * tool. This integer encodes the package, type, and resource
835 * entry. The value 0 is an invalid identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 * @return Drawable An object that can be used to draw this resource.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800837 * @throws NotFoundException Throws NotFoundException if the given ID does
838 * not exist.
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700839 * @see #getDrawable(int, Theme)
Alan Viverettec10e3962014-12-02 14:58:08 -0800840 * @deprecated Use {@link #getDrawable(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 */
Alan Viverettec10e3962014-12-02 14:58:08 -0800842 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700843 public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
Alan Viverette34a14f962014-08-15 16:13:15 -0700844 final Drawable d = getDrawable(id, null);
Alan Viverette7e0aaae2014-11-24 11:27:09 -0800845 if (d != null && d.canApplyTheme()) {
Alan Viverette34a14f962014-08-15 16:13:15 -0700846 Log.w(TAG, "Drawable " + getResourceName(id) + " has unresolved theme "
847 + "attributes! Consider using Resources.getDrawable(int, Theme) or "
848 + "Context.getDrawable(int).", new RuntimeException());
849 }
850 return d;
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800851 }
852
853 /**
854 * Return a drawable object associated with a particular resource ID and
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700855 * styled for the specified theme. Various types of objects will be
856 * returned depending on the underlying resource -- for example, a solid
857 * color, PNG image, scalable image, etc.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800858 *
859 * @param id The desired resource identifier, as generated by the aapt
860 * tool. This integer encodes the package, type, and resource
861 * entry. The value 0 is an invalid identifier.
Alan Viverette3b5c4272014-05-20 13:20:42 -0700862 * @param theme The theme used to style the drawable attributes, may be {@code null}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800863 * @return Drawable An object that can be used to draw this resource.
864 * @throws NotFoundException Throws NotFoundException if the given ID does
865 * not exist.
866 */
Alan Viverette4d07bc92015-11-16 10:19:12 -0500867 public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
868 throws NotFoundException {
Adam Lesinski50954d22017-04-14 18:41:52 -0700869 return getDrawableForDensity(id, 0, theme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 }
871
872 /**
Kenny Root55fc8502010-10-28 14:47:01 -0700873 * Return a drawable object associated with a particular resource ID for the
874 * given screen density in DPI. This will set the drawable's density to be
875 * the device's density multiplied by the ratio of actual drawable density
876 * to requested density. This allows the drawable to be scaled up to the
877 * correct size if needed. Various types of objects will be returned
878 * depending on the underlying resource -- for example, a solid color, PNG
879 * image, scalable image, etc. The Drawable API hides these implementation
880 * details.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800881 *
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700882 * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use
883 * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)}
884 * or {@link #getDrawableForDensity(int, int, Theme)} passing the desired
885 * theme.</p>
886 *
Kenny Root55fc8502010-10-28 14:47:01 -0700887 * @param id The desired resource identifier, as generated by the aapt tool.
888 * This integer encodes the package, type, and resource entry.
889 * The value 0 is an invalid identifier.
890 * @param density the desired screen density indicated by the resource as
Adam Lesinski50954d22017-04-14 18:41:52 -0700891 * found in {@link DisplayMetrics}. A value of 0 means to use the
892 * density returned from {@link #getConfiguration()}.
893 * This is equivalent to calling {@link #getDrawable(int)}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800894 * @return Drawable An object that can be used to draw this resource.
Kenny Root55fc8502010-10-28 14:47:01 -0700895 * @throws NotFoundException Throws NotFoundException if the given ID does
896 * not exist.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800897 * @see #getDrawableForDensity(int, int, Theme)
Alan Viverettea6f8b2c2014-12-02 15:26:33 -0800898 * @deprecated Use {@link #getDrawableForDensity(int, int, Theme)} instead.
Kenny Root55fc8502010-10-28 14:47:01 -0700899 */
Chris Craik1194b0b2018-03-23 13:36:24 -0700900 @Nullable
Alan Viverettea6f8b2c2014-12-02 15:26:33 -0800901 @Deprecated
Alan Viverette4d07bc92015-11-16 10:19:12 -0500902 public Drawable getDrawableForDensity(@DrawableRes int id, int density)
903 throws NotFoundException {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800904 return getDrawableForDensity(id, density, null);
905 }
906
907 /**
908 * Return a drawable object associated with a particular resource ID for the
909 * given screen density in DPI and styled for the specified theme.
910 *
911 * @param id The desired resource identifier, as generated by the aapt tool.
912 * This integer encodes the package, type, and resource entry.
913 * The value 0 is an invalid identifier.
914 * @param density The desired screen density indicated by the resource as
Adam Lesinski50954d22017-04-14 18:41:52 -0700915 * found in {@link DisplayMetrics}. A value of 0 means to use the
916 * density returned from {@link #getConfiguration()}.
917 * This is equivalent to calling {@link #getDrawable(int, Theme)}.
Chris Craik1194b0b2018-03-23 13:36:24 -0700918 * @param theme The theme used to style the drawable attributes, may be {@code null} if the
919 * drawable cannot be decoded.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800920 * @return Drawable An object that can be used to draw this resource.
921 * @throws NotFoundException Throws NotFoundException if the given ID does
Chris Craik1194b0b2018-03-23 13:36:24 -0700922 * not exist.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800923 */
Chris Craik1194b0b2018-03-23 13:36:24 -0700924 @Nullable
Tor Norbye7b9c9122013-05-30 16:48:33 -0700925 public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800926 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500927 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800928 final ResourcesImpl impl = mResourcesImpl;
929 impl.getValueForDensity(id, density, value, true);
Winson9947f1e2019-08-16 10:20:39 -0700930 return loadDrawable(value, id, density, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -0500931 } finally {
932 releaseTempTypedValue(value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800933 }
Kenny Root55fc8502010-10-28 14:47:01 -0700934 }
935
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800936 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100937 @UnsupportedAppUsage
Adam Lesinski50954d22017-04-14 18:41:52 -0700938 Drawable loadDrawable(@NonNull TypedValue value, int id, int density, @Nullable Theme theme)
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800939 throws NotFoundException {
Winson9947f1e2019-08-16 10:20:39 -0700940 ResourceLoader loader = findLoader(value.assetCookie);
941 if (loader != null) {
942 Drawable drawable = loader.loadDrawable(value, id, density, theme);
943 if (drawable != null) {
944 return drawable;
945 }
946 }
947
Adam Lesinski50954d22017-04-14 18:41:52 -0700948 return mResourcesImpl.loadDrawable(this, value, id, density, theme);
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800949 }
950
Kenny Root55fc8502010-10-28 14:47:01 -0700951 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 * Return a movie object associated with the particular resource ID.
953 * @param id The desired resource identifier, as generated by the aapt
954 * tool. This integer encodes the package, type, and resource
955 * entry. The value 0 is an invalid identifier.
956 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
Aurimas Liutikasf0764b52018-08-22 12:55:04 -0700957 *
958 * @deprecated Prefer {@link android.graphics.drawable.AnimatedImageDrawable}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 */
Aurimas Liutikasf0764b52018-08-22 12:55:04 -0700960 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700961 public Movie getMovie(@RawRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800962 final InputStream is = openRawResource(id);
963 final Movie movie = Movie.decodeStream(is);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 try {
965 is.close();
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800966 } catch (IOException e) {
967 // No one cares.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 }
969 return movie;
970 }
971
972 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800973 * Returns a color integer associated with a particular resource ID. If the
974 * resource holds a complex {@link ColorStateList}, then the default color
975 * from the set is returned.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 *
977 * @param id The desired resource identifier, as generated by the aapt
978 * tool. This integer encodes the package, type, and resource
979 * entry. The value 0 is an invalid identifier.
980 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800981 * @throws NotFoundException Throws NotFoundException if the given ID does
982 * not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800984 * @return A single color value in the form 0xAARRGGBB.
985 * @deprecated Use {@link #getColor(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 */
Tor Norbye80756e32015-03-02 09:39:27 -0800987 @ColorInt
Alan Viverette4a357cd2015-03-18 18:37:18 -0700988 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700989 public int getColor(@ColorRes int id) throws NotFoundException {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800990 return getColor(id, null);
991 }
992
993 /**
994 * Returns a themed color integer associated with a particular resource ID.
995 * If the resource holds a complex {@link ColorStateList}, then the default
996 * color from the set is returned.
997 *
998 * @param id The desired resource identifier, as generated by the aapt
999 * tool. This integer encodes the package, type, and resource
1000 * entry. The value 0 is an invalid identifier.
1001 * @param theme The theme used to style the color attributes, may be
1002 * {@code null}.
1003 *
1004 * @throws NotFoundException Throws NotFoundException if the given ID does
1005 * not exist.
1006 *
1007 * @return A single color value in the form 0xAARRGGBB.
1008 */
Tor Norbye80756e32015-03-02 09:39:27 -08001009 @ColorInt
Tor Norbye7b9c9122013-05-30 16:48:33 -07001010 public int getColor(@ColorRes int id, @Nullable Theme theme) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001011 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001012 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001013 final ResourcesImpl impl = mResourcesImpl;
1014 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001016 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 return value.data;
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001018 } else if (value.type != TypedValue.TYPE_STRING) {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001019 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1020 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001022
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001023 final ColorStateList csl = impl.loadColorStateList(this, value, id, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -05001024 return csl.getDefaultColor();
1025 } finally {
1026 releaseTempTypedValue(value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 }
1029
1030 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001031 * Returns a color state list associated with a particular resource ID. The
1032 * resource may contain either a single raw color value or a complex
1033 * {@link ColorStateList} holding multiple possible colors.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 *
1035 * @param id The desired resource identifier of a {@link ColorStateList},
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001036 * as generated by the aapt tool. This integer encodes the
1037 * package, type, and resource entry. The value 0 is an invalid
1038 * identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001040 * @throws NotFoundException Throws NotFoundException if the given ID does
1041 * not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001043 * @return A ColorStateList object containing either a single solid color
1044 * or multiple colors that can be selected based on a state.
1045 * @deprecated Use {@link #getColorStateList(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 */
Chris Craikceb26932018-02-01 15:51:34 -08001047 @NonNull
Alan Viverette4a357cd2015-03-18 18:37:18 -07001048 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -07001049 public ColorStateList getColorStateList(@ColorRes int id) throws NotFoundException {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001050 final ColorStateList csl = getColorStateList(id, null);
1051 if (csl != null && csl.canApplyTheme()) {
1052 Log.w(TAG, "ColorStateList " + getResourceName(id) + " has "
1053 + "unresolved theme attributes! Consider using "
1054 + "Resources.getColorStateList(int, Theme) or "
1055 + "Context.getColorStateList(int).", new RuntimeException());
1056 }
1057 return csl;
1058 }
1059
1060 /**
1061 * Returns a themed color state list associated with a particular resource
1062 * ID. The resource may contain either a single raw color value or a
1063 * complex {@link ColorStateList} holding multiple possible colors.
1064 *
1065 * @param id The desired resource identifier of a {@link ColorStateList},
1066 * as generated by the aapt tool. This integer encodes the
1067 * package, type, and resource entry. The value 0 is an invalid
1068 * identifier.
1069 * @param theme The theme used to style the color attributes, may be
1070 * {@code null}.
1071 *
1072 * @throws NotFoundException Throws NotFoundException if the given ID does
1073 * not exist.
1074 *
1075 * @return A themed ColorStateList object containing either a single solid
1076 * color or multiple colors that can be selected based on a state.
1077 */
Chris Craikceb26932018-02-01 15:51:34 -08001078 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001079 public ColorStateList getColorStateList(@ColorRes int id, @Nullable Theme theme)
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001080 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 final ResourcesImpl impl = mResourcesImpl;
1084 impl.getValue(id, value, true);
1085 return impl.loadColorStateList(this, value, id, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -05001086 } finally {
1087 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 }
1089 }
1090
Chris Craikceb26932018-02-01 15:51:34 -08001091 @NonNull
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001092 ColorStateList loadColorStateList(@NonNull TypedValue value, int id, @Nullable Theme theme)
1093 throws NotFoundException {
1094 return mResourcesImpl.loadColorStateList(this, value, id, theme);
1095 }
1096
Teng-Hui Zhue03c4692016-03-17 10:38:43 -07001097 /**
1098 * @hide
1099 */
Chris Craikceb26932018-02-01 15:51:34 -08001100 @NonNull
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001101 public ComplexColor loadComplexColor(@NonNull TypedValue value, int id, @Nullable Theme theme) {
1102 return mResourcesImpl.loadComplexColor(this, value, id, theme);
1103 }
1104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 /**
1106 * Return a boolean associated with a particular resource ID. This can be
1107 * used with any integral resource value, and will return true if it is
1108 * non-zero.
1109 *
1110 * @param id The desired resource identifier, as generated by the aapt
1111 * tool. This integer encodes the package, type, and resource
1112 * entry. The value 0 is an invalid identifier.
1113 *
1114 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1115 *
1116 * @return Returns the boolean value contained in the resource.
1117 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001118 public boolean getBoolean(@BoolRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001119 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001120 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001121 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette4d07bc92015-11-16 10:19:12 -05001123 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 return value.data != 0;
1125 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001126 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1127 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1128 } finally {
1129 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 }
1131 }
1132
1133 /**
1134 * Return an integer associated with a particular resource ID.
1135 *
1136 * @param id The desired resource identifier, as generated by the aapt
1137 * tool. This integer encodes the package, type, and resource
1138 * entry. The value 0 is an invalid identifier.
1139 *
1140 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1141 *
1142 * @return Returns the integer value contained in the resource.
1143 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001144 public int getInteger(@IntegerRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001145 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001146 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001147 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette4d07bc92015-11-16 10:19:12 -05001149 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 return value.data;
1151 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001152 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1153 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1154 } finally {
1155 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001156 }
1157 }
1158
1159 /**
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001160 * Retrieve a floating-point value for a particular resource ID.
1161 *
1162 * @param id The desired resource identifier, as generated by the aapt
1163 * tool. This integer encodes the package, type, and resource
1164 * entry. The value 0 is an invalid identifier.
1165 *
1166 * @return Returns the floating-point value contained in the resource.
1167 *
1168 * @throws NotFoundException Throws NotFoundException if the given ID does
1169 * not exist or is not a floating-point value.
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001170 */
Jake Wharton32365b92018-09-07 16:09:21 -04001171 public float getFloat(@DimenRes int id) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001172 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001173 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001174 mResourcesImpl.getValue(id, value, true);
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001175 if (value.type == TypedValue.TYPE_FLOAT) {
1176 return value.getFloat();
1177 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001178 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1179 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1180 } finally {
1181 releaseTempTypedValue(value);
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001182 }
1183 }
1184
1185 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 * Return an XmlResourceParser through which you can read a view layout
1187 * description for the given resource ID. This parser has limited
1188 * functionality -- in particular, you can't change its input, and only
1189 * the high-level events are available.
1190 *
1191 * <p>This function is really a simple wrapper for calling
1192 * {@link #getXml} with a layout resource.
1193 *
1194 * @param id The desired resource identifier, as generated by the aapt
1195 * tool. This integer encodes the package, type, and resource
1196 * entry. The value 0 is an invalid identifier.
1197 *
1198 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1199 *
1200 * @return A new parser object through which you can read
1201 * the XML data.
1202 *
1203 * @see #getXml
1204 */
Chris Craikceb26932018-02-01 15:51:34 -08001205 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001206 public XmlResourceParser getLayout(@LayoutRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 return loadXmlResourceParser(id, "layout");
1208 }
1209
1210 /**
1211 * Return an XmlResourceParser through which you can read an animation
1212 * description for the given resource ID. This parser has limited
1213 * functionality -- in particular, you can't change its input, and only
1214 * the high-level events are available.
1215 *
1216 * <p>This function is really a simple wrapper for calling
1217 * {@link #getXml} with an animation resource.
1218 *
1219 * @param id The desired resource identifier, as generated by the aapt
1220 * tool. This integer encodes the package, type, and resource
1221 * entry. The value 0 is an invalid identifier.
1222 *
1223 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1224 *
1225 * @return A new parser object through which you can read
1226 * the XML data.
1227 *
1228 * @see #getXml
1229 */
Chris Craikceb26932018-02-01 15:51:34 -08001230 @NonNull
ztenghuib5292562017-07-11 16:03:36 -07001231 public XmlResourceParser getAnimation(@AnimatorRes @AnimRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 return loadXmlResourceParser(id, "anim");
1233 }
1234
1235 /**
1236 * Return an XmlResourceParser through which you can read a generic XML
1237 * resource for the given resource ID.
1238 *
1239 * <p>The XmlPullParser implementation returned here has some limited
1240 * functionality. In particular, you can't change its input, and only
1241 * high-level parsing events are available (since the document was
1242 * pre-parsed for you at build time, which involved merging text and
1243 * stripping comments).
1244 *
1245 * @param id The desired resource identifier, as generated by the aapt
1246 * tool. This integer encodes the package, type, and resource
1247 * entry. The value 0 is an invalid identifier.
1248 *
1249 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1250 *
1251 * @return A new parser object through which you can read
1252 * the XML data.
1253 *
1254 * @see android.util.AttributeSet
1255 */
Chris Craikceb26932018-02-01 15:51:34 -08001256 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001257 public XmlResourceParser getXml(@XmlRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 return loadXmlResourceParser(id, "xml");
1259 }
1260
1261 /**
1262 * Open a data stream for reading a raw resource. This can only be used
1263 * with resources whose value is the name of an asset files -- that is, it can be
1264 * used to open drawable, sound, and raw resources; it will fail on string
1265 * and color resources.
1266 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001267 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 *
1269 * @return InputStream Access to the resource data.
1270 *
1271 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 */
Chris Craikceb26932018-02-01 15:51:34 -08001273 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001274 public InputStream openRawResource(@RawRes int id) throws NotFoundException {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001275 final TypedValue value = obtainTempTypedValue();
1276 try {
1277 return openRawResource(id, value);
1278 } finally {
1279 releaseTempTypedValue(value);
1280 }
1281 }
1282
1283 /**
Alan Viverette4d07bc92015-11-16 10:19:12 -05001284 * Returns a TypedValue suitable for temporary use. The obtained TypedValue
1285 * should be released using {@link #releaseTempTypedValue(TypedValue)}.
1286 *
1287 * @return a typed value suitable for temporary use
1288 */
1289 private TypedValue obtainTempTypedValue() {
1290 TypedValue tmpValue = null;
1291 synchronized (mTmpValueLock) {
1292 if (mTmpValue != null) {
1293 tmpValue = mTmpValue;
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001294 mTmpValue = null;
1295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001297 if (tmpValue == null) {
1298 return new TypedValue();
1299 }
1300 return tmpValue;
1301 }
1302
1303 /**
1304 * Returns a TypedValue to the pool. After calling this method, the
1305 * specified TypedValue should no longer be accessed.
1306 *
1307 * @param value the typed value to return to the pool
1308 */
1309 private void releaseTempTypedValue(TypedValue value) {
1310 synchronized (mTmpValueLock) {
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001311 if (mTmpValue == null) {
1312 mTmpValue = value;
1313 }
1314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 }
1316
1317 /**
1318 * Open a data stream for reading a raw resource. This can only be used
Andy Stadlerf8a7cea2009-04-10 16:24:47 -07001319 * 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 -08001320 * used to open drawable, sound, and raw resources; it will fail on string
1321 * and color resources.
1322 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001323 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 * @param value The TypedValue object to hold the resource information.
1325 *
1326 * @return InputStream Access to the resource data.
1327 *
1328 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 */
Chris Craikceb26932018-02-01 15:51:34 -08001330 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001331 public InputStream openRawResource(@RawRes int id, TypedValue value)
1332 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001333 return mResourcesImpl.openRawResource(id, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 }
1335
1336 /**
1337 * Open a file descriptor for reading a raw resource. This can only be used
1338 * with resources whose value is the name of an asset files -- that is, it can be
1339 * used to open drawable, sound, and raw resources; it will fail on string
1340 * and color resources.
1341 *
1342 * <p>This function only works for resources that are stored in the package
1343 * as uncompressed data, which typically includes things like mp3 files
1344 * and png images.
1345 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001346 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 *
1348 * @return AssetFileDescriptor A new file descriptor you can use to read
1349 * the resource. This includes the file descriptor itself, as well as the
1350 * offset and length of data where the resource appears in the file. A
1351 * null is returned if the file exists but is compressed.
1352 *
1353 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1354 *
1355 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001356 public AssetFileDescriptor openRawResourceFd(@RawRes int id)
1357 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001358 final TypedValue value = obtainTempTypedValue();
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001359 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001360 return mResourcesImpl.openRawResourceFd(id, value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001361 } finally {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001362 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 }
1364 }
1365
1366 /**
1367 * Return the raw data associated with a particular resource ID.
1368 *
1369 * @param id The desired resource identifier, as generated by the aapt
1370 * tool. This integer encodes the package, type, and resource
1371 * entry. The value 0 is an invalid identifier.
1372 * @param outValue Object in which to place the resource data.
1373 * @param resolveRefs If true, a resource that is a reference to another
1374 * resource will be followed so that you receive the
1375 * actual final resource data. If false, the TypedValue
1376 * will be filled in with the reference itself.
1377 *
1378 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1379 *
1380 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001381 public void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001383 mResourcesImpl.getValue(id, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 }
1385
1386 /**
Kenny Root55fc8502010-10-28 14:47:01 -07001387 * Get the raw value associated with a resource with associated density.
1388 *
1389 * @param id resource identifier
1390 * @param density density in DPI
1391 * @param resolveRefs If true, a resource that is a reference to another
1392 * resource will be followed so that you receive the actual final
1393 * resource data. If false, the TypedValue will be filled in with
1394 * the reference itself.
1395 * @throws NotFoundException Throws NotFoundException if the given ID does
1396 * not exist.
1397 * @see #getValue(String, TypedValue, boolean)
Kenny Root55fc8502010-10-28 14:47:01 -07001398 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001399 public void getValueForDensity(@AnyRes int id, int density, TypedValue outValue,
1400 boolean resolveRefs) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001401 mResourcesImpl.getValueForDensity(id, density, outValue, resolveRefs);
Kenny Root55fc8502010-10-28 14:47:01 -07001402 }
1403
1404 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 * Return the raw data associated with a particular resource ID.
1406 * See getIdentifier() for information on how names are mapped to resource
1407 * IDs, and getString(int) for information on how string resources are
1408 * retrieved.
1409 *
1410 * <p>Note: use of this function is discouraged. It is much more
1411 * efficient to retrieve resources by identifier than by name.
1412 *
1413 * @param name The name of the desired resource. This is passed to
1414 * getIdentifier() with a default type of "string".
1415 * @param outValue Object in which to place the resource data.
1416 * @param resolveRefs If true, a resource that is a reference to another
1417 * resource will be followed so that you receive the
1418 * actual final resource data. If false, the TypedValue
1419 * will be filled in with the reference itself.
1420 *
1421 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1422 *
1423 */
1424 public void getValue(String name, TypedValue outValue, boolean resolveRefs)
1425 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001426 mResourcesImpl.getValue(name, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 }
1428
Aurimas Liutikasaae06632019-01-30 13:16:27 -08001429
1430 /**
Aurimas Liutikas29a90d62019-03-07 15:47:38 -08001431 * Returns the resource ID of the resource that was used to create this AttributeSet.
1432 *
Aurimas Liutikasaae06632019-01-30 13:16:27 -08001433 * @param set AttributeSet for which we want to find the source.
Aurimas Liutikas29a90d62019-03-07 15:47:38 -08001434 * @return The resource ID for the source that is backing the given AttributeSet or
1435 * {@link Resources#ID_NULL} if the AttributeSet is {@code null}.
Aurimas Liutikasaae06632019-01-30 13:16:27 -08001436 */
1437 @AnyRes
1438 public static int getAttributeSetSourceResId(@Nullable AttributeSet set) {
1439 return ResourcesImpl.getAttributeSetSourceResId(set);
1440 }
1441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 /**
1443 * This class holds the current attribute values for a particular theme.
1444 * In other words, a Theme is a set of values for resource attributes;
1445 * these are used in conjunction with {@link TypedArray}
1446 * to resolve the final value for an attribute.
1447 *
1448 * <p>The Theme's attributes come into play in two ways: (1) a styled
1449 * attribute can explicit reference a value in the theme through the
1450 * "?themeAttribute" syntax; (2) if no value has been defined for a
1451 * particular styled attribute, as a last resort we will try to find that
1452 * attribute's value in the Theme.
1453 *
1454 * <p>You will normally use the {@link #obtainStyledAttributes} APIs to
1455 * retrieve XML attributes with style and theme information applied.
1456 */
1457 public final class Theme {
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001458 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001459 private ResourcesImpl.ThemeImpl mThemeImpl;
1460
1461 private Theme() {
1462 }
1463
1464 void setImpl(ResourcesImpl.ThemeImpl impl) {
1465 mThemeImpl = impl;
1466 }
1467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 /**
1469 * Place new attribute values into the theme. The style resource
1470 * specified by <var>resid</var> will be retrieved from this Theme's
1471 * resources, its values placed into the Theme object.
1472 *
1473 * <p>The semantics of this function depends on the <var>force</var>
1474 * argument: If false, only values that are not already defined in
1475 * the theme will be copied from the system resource; otherwise, if
1476 * any of the style's attributes are already defined in the theme, the
1477 * current values in the theme will be overwritten.
1478 *
Alan Viverette75257ce2014-05-22 19:31:38 -07001479 * @param resId The resource ID of a style resource from which to
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 * obtain attribute values.
1481 * @param force If true, values in the style resource will always be
1482 * used in the theme; otherwise, they will only be used
1483 * if not already defined in the theme.
1484 */
Alan Viverette75257ce2014-05-22 19:31:38 -07001485 public void applyStyle(int resId, boolean force) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001486 mThemeImpl.applyStyle(resId, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 }
1488
1489 /**
1490 * Set this theme to hold the same contents as the theme
1491 * <var>other</var>. If both of these themes are from the same
1492 * Resources object, they will be identical after this function
1493 * returns. If they are from different Resources, only the resources
1494 * they have in common will be set in this theme.
1495 *
1496 * @param other The existing Theme to copy from.
1497 */
1498 public void setTo(Theme other) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001499 mThemeImpl.setTo(other.mThemeImpl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 }
1501
1502 /**
John Spurlock330dd532012-12-18 12:03:11 -05001503 * Return a TypedArray holding the values defined by
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 * <var>Theme</var> which are listed in <var>attrs</var>.
1505 *
Scott Main183bf112012-08-13 19:12:13 -07001506 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1507 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 *
Adam Lesinski5ec88752017-04-12 14:45:14 -07001509 * @param attrs The desired attributes. These attribute IDs must be sorted in ascending
1510 * order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 *
1512 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1513 *
1514 * @return Returns a TypedArray holding an array of the attribute values.
1515 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1516 * when done with it.
1517 *
1518 * @see Resources#obtainAttributes
1519 * @see #obtainStyledAttributes(int, int[])
1520 * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
1521 */
Aurimas Liutikas77acf4b2018-12-19 17:31:03 -08001522 @NonNull
1523 public TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001524 return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 }
1526
1527 /**
John Spurlock330dd532012-12-18 12:03:11 -05001528 * Return a TypedArray holding the values defined by the style
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 * resource <var>resid</var> which are listed in <var>attrs</var>.
1530 *
Scott Main183bf112012-08-13 19:12:13 -07001531 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1532 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 *
Alan Viverette395cd012015-08-11 17:27:04 -04001534 * @param resId The desired style resource.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001535 * @param attrs The desired attributes in the style. These attribute IDs must be sorted in
1536 * ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 *
1538 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1539 *
1540 * @return Returns a TypedArray holding an array of the attribute values.
1541 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1542 * when done with it.
1543 *
1544 * @see Resources#obtainAttributes
1545 * @see #obtainStyledAttributes(int[])
1546 * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
1547 */
Aurimas Liutikas77acf4b2018-12-19 17:31:03 -08001548 @NonNull
1549 public TypedArray obtainStyledAttributes(@StyleRes int resId,
1550 @NonNull @StyleableRes int[] attrs)
Tor Norbyec91531a2015-04-01 17:41:55 -07001551 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001552 return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, resId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 }
1554
1555 /**
John Spurlock330dd532012-12-18 12:03:11 -05001556 * Return a TypedArray holding the attribute values in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 * <var>set</var>
1558 * that are listed in <var>attrs</var>. In addition, if the given
1559 * AttributeSet specifies a style class (through the "style" attribute),
1560 * that style will be applied on top of the base attributes it defines.
1561 *
Scott Main183bf112012-08-13 19:12:13 -07001562 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1563 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 *
1565 * <p>When determining the final value of a particular attribute, there
1566 * are four inputs that come into play:</p>
1567 *
1568 * <ol>
1569 * <li> Any attribute values in the given AttributeSet.
1570 * <li> The style resource specified in the AttributeSet (named
1571 * "style").
1572 * <li> The default style specified by <var>defStyleAttr</var> and
1573 * <var>defStyleRes</var>
1574 * <li> The base values in this theme.
1575 * </ol>
1576 *
1577 * <p>Each of these inputs is considered in-order, with the first listed
1578 * taking precedence over the following ones. In other words, if in the
1579 * AttributeSet you have supplied <code>&lt;Button
1580 * textColor="#ff000000"&gt;</code>, then the button's text will
1581 * <em>always</em> be black, regardless of what is specified in any of
1582 * the styles.
1583 *
1584 * @param set The base set of attribute values. May be null.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001585 * @param attrs The desired attributes to be retrieved. These attribute IDs must be sorted
1586 * in ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 * @param defStyleAttr An attribute in the current theme that contains a
1588 * reference to a style resource that supplies
John Spurlock330dd532012-12-18 12:03:11 -05001589 * defaults values for the TypedArray. Can be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001590 * 0 to not look for defaults.
1591 * @param defStyleRes A resource identifier of a style resource that
John Spurlock330dd532012-12-18 12:03:11 -05001592 * supplies default values for the TypedArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 * used only if defStyleAttr is 0 or can not be found
1594 * in the theme. Can be 0 to not look for defaults.
1595 *
1596 * @return Returns a TypedArray holding an array of the attribute values.
1597 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1598 * when done with it.
1599 *
1600 * @see Resources#obtainAttributes
1601 * @see #obtainStyledAttributes(int[])
1602 * @see #obtainStyledAttributes(int, int[])
1603 */
Aurimas Liutikas77acf4b2018-12-19 17:31:03 -08001604 @NonNull
1605 public TypedArray obtainStyledAttributes(@Nullable AttributeSet set,
1606 @NonNull @StyleableRes int[] attrs, @AttrRes int defStyleAttr,
1607 @StyleRes int defStyleRes) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001608 return mThemeImpl.obtainStyledAttributes(this, set, attrs, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 }
1610
1611 /**
Alan Viverette52b999f2014-03-24 18:00:26 -07001612 * Retrieve the values for a set of attributes in the Theme. The
1613 * contents of the typed array are ultimately filled in by
1614 * {@link Resources#getValue}.
1615 *
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001616 * @param values The base set of attribute values, must be equal in
1617 * length to {@code attrs}. All values must be of type
1618 * {@link TypedValue#TYPE_ATTRIBUTE}.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001619 * @param attrs The desired attributes to be retrieved. These attribute IDs must be sorted
1620 * in ascending order.
Alan Viverette52b999f2014-03-24 18:00:26 -07001621 * @return Returns a TypedArray holding an array of the attribute
1622 * values. Be sure to call {@link TypedArray#recycle()}
1623 * when done with it.
1624 * @hide
1625 */
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001626 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001627 @UnsupportedAppUsage
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001628 public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001629 return mThemeImpl.resolveAttributes(this, values, attrs);
Alan Viverette52b999f2014-03-24 18:00:26 -07001630 }
1631
1632 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 * Retrieve the value of an attribute in the Theme. The contents of
1634 * <var>outValue</var> are ultimately filled in by
1635 * {@link Resources#getValue}.
1636 *
1637 * @param resid The resource identifier of the desired theme
1638 * attribute.
1639 * @param outValue Filled in with the ultimate resource value supplied
1640 * by the attribute.
1641 * @param resolveRefs If true, resource references will be walked; if
1642 * false, <var>outValue</var> may be a
1643 * TYPE_REFERENCE. In either case, it will never
1644 * be a TYPE_ATTRIBUTE.
1645 *
1646 * @return boolean Returns true if the attribute was found and
1647 * <var>outValue</var> is valid, else false.
1648 */
Alan Viverette52b999f2014-03-24 18:00:26 -07001649 public boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001650 return mThemeImpl.resolveAttribute(resid, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 }
1652
1653 /**
Jon Miranda042ad632014-09-03 17:57:35 -07001654 * Gets all of the attribute ids associated with this {@link Theme}. For debugging only.
1655 *
1656 * @return The int array containing attribute ids associated with this {@link Theme}.
1657 * @hide
1658 */
1659 public int[] getAllAttributes() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001660 return mThemeImpl.getAllAttributes();
Jon Miranda042ad632014-09-03 17:57:35 -07001661 }
1662
1663 /**
Alan Viverette52b999f2014-03-24 18:00:26 -07001664 * Returns the resources to which this theme belongs.
1665 *
1666 * @return Resources to which this theme belongs.
1667 */
1668 public Resources getResources() {
1669 return Resources.this;
1670 }
1671
1672 /**
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001673 * Return a drawable object associated with a particular resource ID
1674 * and styled for the Theme.
1675 *
1676 * @param id The desired resource identifier, as generated by the aapt
1677 * tool. This integer encodes the package, type, and resource
1678 * entry. The value 0 is an invalid identifier.
1679 * @return Drawable An object that can be used to draw this resource.
1680 * @throws NotFoundException Throws NotFoundException if the given ID
1681 * does not exist.
1682 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001683 public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001684 return Resources.this.getDrawable(id, this);
1685 }
1686
1687 /**
Alan Viverettec1d52792015-05-05 09:49:03 -07001688 * Returns a bit mask of configuration changes that will impact this
1689 * theme (and thus require completely reloading it).
1690 *
1691 * @return a bit mask of configuration changes, as defined by
1692 * {@link ActivityInfo}
1693 * @see ActivityInfo
1694 */
Alan Viverette9ad386b2017-01-26 14:00:20 -05001695 public @Config int getChangingConfigurations() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001696 return mThemeImpl.getChangingConfigurations();
Alan Viverettec1d52792015-05-05 09:49:03 -07001697 }
1698
1699 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001700 * Print contents of this theme out to the log. For debugging only.
1701 *
1702 * @param priority The log priority to use.
1703 * @param tag The log tag to use.
1704 * @param prefix Text to prefix each line printed.
1705 */
1706 public void dump(int priority, String tag, String prefix) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001707 mThemeImpl.dump(priority, tag, prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001708 }
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001709
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001710 // Needed by layoutlib.
1711 /*package*/ long getNativeTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001712 return mThemeImpl.getNativeTheme();
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001713 }
1714
1715 /*package*/ int getAppliedStyleResId() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001716 return mThemeImpl.getAppliedStyleResId();
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001717 }
Alan Viverette75257ce2014-05-22 19:31:38 -07001718
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001719 /**
1720 * @hide
1721 */
1722 public ThemeKey getKey() {
1723 return mThemeImpl.getKey();
Alan Viverette75257ce2014-05-22 19:31:38 -07001724 }
Jon Miranda836c0a82014-08-11 12:32:26 -07001725
1726 private String getResourceNameFromHexString(String hexString) {
1727 return getResourceName(Integer.parseInt(hexString, 16));
1728 }
1729
1730 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001731 * Parses {@link #getKey()} and returns a String array that holds pairs of
Alan Viverettee54d2452015-05-06 10:41:43 -07001732 * adjacent Theme data: resource name followed by whether or not it was
1733 * forced, as specified by {@link #applyStyle(int, boolean)}.
Jon Miranda836c0a82014-08-11 12:32:26 -07001734 *
1735 * @hide
1736 */
1737 @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
1738 public String[] getTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001739 return mThemeImpl.getTheme();
Jon Miranda836c0a82014-08-11 12:32:26 -07001740 }
Alan Viverettee54d2452015-05-06 10:41:43 -07001741
Siva Velusamy0d857b92015-04-22 10:23:56 -07001742 /** @hide */
1743 public void encode(@NonNull ViewHierarchyEncoder encoder) {
1744 encoder.beginObject(this);
Alan Viveretteac674092015-05-08 11:04:47 -07001745 final String[] properties = getTheme();
Siva Velusamy0d857b92015-04-22 10:23:56 -07001746 for (int i = 0; i < properties.length; i += 2) {
1747 encoder.addProperty(properties[i], properties[i+1]);
1748 }
1749 encoder.endObject();
1750 }
1751
Alan Viverettee54d2452015-05-06 10:41:43 -07001752 /**
1753 * Rebases the theme against the parent Resource object's current
1754 * configuration by re-applying the styles passed to
1755 * {@link #applyStyle(int, boolean)}.
Alan Viverettee54d2452015-05-06 10:41:43 -07001756 */
1757 public void rebase() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001758 mThemeImpl.rebase();
Alan Viverettee54d2452015-05-06 10:41:43 -07001759 }
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001760
1761 /**
1762 * Returns the resource ID for the style specified using {@code style="..."} in the
1763 * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise if not
1764 * specified or otherwise not applicable.
1765 * <p>
1766 * Each {@link android.view.View} can have an explicit style specified in the layout file.
1767 * This style is used first during the {@link android.view.View} attribute resolution, then
1768 * if an attribute is not defined there the resource system looks at default style and theme
1769 * as fallbacks.
1770 *
1771 * @param set The base set of attribute values.
1772 *
1773 * @return The resource ID for the style specified using {@code style="..."} in the
1774 * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise
1775 * if not specified or otherwise not applicable.
1776 */
1777 @StyleRes
1778 public int getExplicitStyle(@Nullable AttributeSet set) {
1779 if (set == null) {
1780 return ID_NULL;
1781 }
1782 int styleAttr = set.getStyleAttribute();
1783 if (styleAttr == ID_NULL) {
1784 return ID_NULL;
1785 }
1786 String styleAttrType = getResources().getResourceTypeName(styleAttr);
1787 if ("attr".equals(styleAttrType)) {
1788 TypedValue explicitStyle = new TypedValue();
1789 boolean resolved = resolveAttribute(styleAttr, explicitStyle, true);
1790 if (resolved) {
1791 return explicitStyle.resourceId;
1792 }
1793 } else if ("style".equals(styleAttrType)) {
1794 return styleAttr;
1795 }
1796 return ID_NULL;
1797 }
1798
1799 /**
1800 * Returns the ordered list of resource ID that are considered when resolving attribute
1801 * values when making an equivalent call to
1802 * {@link #obtainStyledAttributes(AttributeSet, int[], int, int)} . The list will include
1803 * a set of explicit styles ({@code explicitStyleRes} and it will include the default styles
1804 * ({@code defStyleAttr} and {@code defStyleRes}).
1805 *
1806 * @param defStyleAttr An attribute in the current theme that contains a
1807 * reference to a style resource that supplies
1808 * defaults values for the TypedArray. Can be
1809 * 0 to not look for defaults.
1810 * @param defStyleRes A resource identifier of a style resource that
1811 * supplies default values for the TypedArray,
1812 * used only if defStyleAttr is 0 or can not be found
1813 * in the theme. Can be 0 to not look for defaults.
1814 * @param explicitStyleRes A resource identifier of an explicit style resource.
1815 * @return ordered list of resource ID that are considered when resolving attribute values.
1816 */
Aurimas Liutikas6c15bc02019-02-28 11:16:06 -08001817 @NonNull
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001818 public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr,
1819 @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) {
Aurimas Liutikas6c15bc02019-02-28 11:16:06 -08001820 int[] stack = mThemeImpl.getAttributeResolutionStack(
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001821 defStyleAttr, defStyleRes, explicitStyleRes);
Aurimas Liutikas6c15bc02019-02-28 11:16:06 -08001822 if (stack == null) {
1823 return new int[0];
1824 } else {
1825 return stack;
1826 }
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001827 }
Alan Viverettee54d2452015-05-06 10:41:43 -07001828 }
1829
1830 static class ThemeKey implements Cloneable {
1831 int[] mResId;
1832 boolean[] mForce;
1833 int mCount;
1834
1835 private int mHashCode = 0;
1836
1837 public void append(int resId, boolean force) {
1838 if (mResId == null) {
1839 mResId = new int[4];
1840 }
1841
1842 if (mForce == null) {
1843 mForce = new boolean[4];
1844 }
1845
1846 mResId = GrowingArrayUtils.append(mResId, mCount, resId);
1847 mForce = GrowingArrayUtils.append(mForce, mCount, force);
1848 mCount++;
1849
1850 mHashCode = 31 * (31 * mHashCode + resId) + (force ? 1 : 0);
1851 }
1852
1853 /**
1854 * Sets up this key as a deep copy of another key.
1855 *
1856 * @param other the key to deep copy into this key
1857 */
1858 public void setTo(ThemeKey other) {
1859 mResId = other.mResId == null ? null : other.mResId.clone();
1860 mForce = other.mForce == null ? null : other.mForce.clone();
1861 mCount = other.mCount;
Hiroshi Sumita4a3beba2019-02-25 18:52:24 +09001862 mHashCode = other.mHashCode;
Alan Viverettee54d2452015-05-06 10:41:43 -07001863 }
1864
1865 @Override
1866 public int hashCode() {
1867 return mHashCode;
1868 }
1869
1870 @Override
1871 public boolean equals(Object o) {
1872 if (this == o) {
1873 return true;
1874 }
1875
1876 if (o == null || getClass() != o.getClass() || hashCode() != o.hashCode()) {
1877 return false;
1878 }
1879
1880 final ThemeKey t = (ThemeKey) o;
1881 if (mCount != t.mCount) {
1882 return false;
1883 }
1884
1885 final int N = mCount;
1886 for (int i = 0; i < N; i++) {
1887 if (mResId[i] != t.mResId[i] || mForce[i] != t.mForce[i]) {
1888 return false;
1889 }
1890 }
1891
1892 return true;
1893 }
1894
1895 /**
1896 * @return a shallow copy of this key
1897 */
1898 @Override
1899 public ThemeKey clone() {
1900 final ThemeKey other = new ThemeKey();
1901 other.mResId = mResId;
1902 other.mForce = mForce;
1903 other.mCount = mCount;
John Reck4feb3262015-07-13 14:42:43 -07001904 other.mHashCode = mHashCode;
Alan Viverettee54d2452015-05-06 10:41:43 -07001905 return other;
1906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 }
1908
1909 /**
1910 * Generate a new Theme object for this set of Resources. It initially
1911 * starts out empty.
Jon Miranda836c0a82014-08-11 12:32:26 -07001912 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 * @return Theme The newly created Theme container.
1914 */
1915 public final Theme newTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001916 Theme theme = new Theme();
1917 theme.setImpl(mResourcesImpl.newThemeImpl());
Adam Lesinski4fed9712017-05-23 13:14:54 -07001918 synchronized (mThemeRefs) {
1919 mThemeRefs.add(new WeakReference<>(theme));
Richard Uhlerdd6a0db2018-04-26 15:09:30 +01001920
1921 // Clean up references to garbage collected themes
1922 if (mThemeRefs.size() > mThemeRefsNextFlushSize) {
1923 mThemeRefs.removeIf(ref -> ref.get() == null);
1924 mThemeRefsNextFlushSize = Math.max(MIN_THEME_REFS_FLUSH_SIZE,
1925 2 * mThemeRefs.size());
1926 }
Adam Lesinski4fed9712017-05-23 13:14:54 -07001927 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001928 return theme;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001929 }
1930
1931 /**
1932 * Retrieve a set of basic attribute values from an AttributeSet, not
1933 * performing styling of them using a theme and/or style resources.
Jon Miranda836c0a82014-08-11 12:32:26 -07001934 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001935 * @param set The current attribute values to retrieve.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001936 * @param attrs The specific attributes to be retrieved. These attribute IDs must be sorted in
1937 * ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001938 * @return Returns a TypedArray holding an array of the attribute values.
1939 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1940 * when done with it.
1941 *
1942 * @see Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
1943 */
Adam Lesinski5ec88752017-04-12 14:45:14 -07001944 public TypedArray obtainAttributes(AttributeSet set, @StyleableRes int[] attrs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 int len = attrs.length;
Alan Viverette52b999f2014-03-24 18:00:26 -07001946 TypedArray array = TypedArray.obtain(this, len);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001947
1948 // XXX note that for now we only work with compiled XML files.
1949 // To support generic XML files we will need to manually parse
1950 // out the attributes from the XML file (applying type information
1951 // contained in the resources and such).
1952 XmlBlock.Parser parser = (XmlBlock.Parser)set;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001953 mResourcesImpl.getAssets().retrieveAttributes(parser, attrs, array.mData, array.mIndices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 array.mXml = parser;
1956
1957 return array;
1958 }
Mitsuru Oshimae5fb3282009-06-09 21:16:08 -07001959
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 /**
1961 * Store the newly updated configuration.
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -07001962 *
1963 * @deprecated See {@link android.content.Context#createConfigurationContext(Configuration)}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 */
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -07001965 @Deprecated
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001966 public void updateConfiguration(Configuration config, DisplayMetrics metrics) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001967 updateConfiguration(config, metrics, null);
1968 }
1969
1970 /**
1971 * @hide
1972 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001973 public void updateConfiguration(Configuration config, DisplayMetrics metrics,
1974 CompatibilityInfo compat) {
1975 mResourcesImpl.updateConfiguration(config, metrics, compat);
Narayan Kamath21fc8ba2014-03-05 18:42:23 +00001976 }
1977
1978 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 * Update the system resources configuration if they have previously
1980 * been initialized.
1981 *
1982 * @hide
1983 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001984 @UnsupportedAppUsage
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001985 public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics,
1986 CompatibilityInfo compat) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 if (mSystem != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001988 mSystem.updateConfiguration(config, metrics, compat);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 //Log.i(TAG, "Updated system resources " + mSystem
1990 // + ": " + mSystem.getConfiguration());
1991 }
1992 }
1993
1994 /**
1995 * Return the current display metrics that are in effect for this resource
1996 * object. The returned object should be treated as read-only.
1997 *
1998 * @return The resource's current display metrics.
1999 */
2000 public DisplayMetrics getDisplayMetrics() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002001 return mResourcesImpl.getDisplayMetrics();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002002 }
2003
Adam Lesinski4ece3d62016-06-16 18:05:41 -07002004 /** @hide */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002005 @UnsupportedAppUsage
Adam Lesinski4ece3d62016-06-16 18:05:41 -07002006 public DisplayAdjustments getDisplayAdjustments() {
2007 return mResourcesImpl.getDisplayAdjustments();
2008 }
2009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002010 /**
2011 * Return the current configuration that is in effect for this resource
2012 * object. The returned object should be treated as read-only.
2013 *
2014 * @return The resource's current configuration.
2015 */
2016 public Configuration getConfiguration() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002017 return mResourcesImpl.getConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002018 }
Filip Gruszczynski23493322015-07-29 17:02:59 -07002019
2020 /** @hide */
2021 public Configuration[] getSizeConfigurations() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002022 return mResourcesImpl.getSizeConfigurations();
2023 }
Filip Gruszczynski23493322015-07-29 17:02:59 -07002024
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002025 /**
2026 * Return the compatibility mode information for the application.
2027 * The returned object should be treated as read-only.
2028 *
Dianne Hackborn3904d032011-05-27 12:09:11 -07002029 * @return compatibility info.
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002030 * @hide
2031 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002032 @UnsupportedAppUsage
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002033 public CompatibilityInfo getCompatibilityInfo() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002034 return mResourcesImpl.getCompatibilityInfo();
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036
2037 /**
Dianne Hackborna53b8282009-07-17 11:13:48 -07002038 * This is just for testing.
2039 * @hide
2040 */
Adam Lesinski082614c2016-03-04 14:33:47 -08002041 @VisibleForTesting
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002042 @UnsupportedAppUsage
Dianne Hackborna53b8282009-07-17 11:13:48 -07002043 public void setCompatibilityInfo(CompatibilityInfo ci) {
Adam Lesinski79a8ffe2013-09-19 20:33:15 -07002044 if (ci != null) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002045 mResourcesImpl.updateConfiguration(null, null, ci);
Adam Lesinski79a8ffe2013-09-19 20:33:15 -07002046 }
Dianne Hackborna53b8282009-07-17 11:13:48 -07002047 }
2048
2049 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002050 * Return a resource identifier for the given resource name. A fully
2051 * qualified resource name is of the form "package:type/entry". The first
2052 * two components (package and type) are optional if defType and
2053 * defPackage, respectively, are specified here.
2054 *
2055 * <p>Note: use of this function is discouraged. It is much more
2056 * efficient to retrieve resources by identifier than by name.
2057 *
2058 * @param name The name of the desired resource.
2059 * @param defType Optional default resource type to find, if "type/" is
2060 * not included in the name. Can be null to require an
2061 * explicit type.
2062 * @param defPackage Optional default package to find, if "package:" is
2063 * not included in the name. Can be null to require an
2064 * explicit package.
2065 *
2066 * @return int The associated resource identifier. Returns 0 if no such
2067 * resource was found. (0 is not a valid resource ID.)
2068 */
2069 public int getIdentifier(String name, String defType, String defPackage) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002070 return mResourcesImpl.getIdentifier(name, defType, defPackage);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002071 }
2072
2073 /**
Jeff Sharkey47b50332013-03-15 14:46:46 -07002074 * Return true if given resource identifier includes a package.
2075 *
2076 * @hide
2077 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002078 public static boolean resourceHasPackage(@AnyRes int resid) {
Jeff Sharkey47b50332013-03-15 14:46:46 -07002079 return (resid >>> 24) != 0;
2080 }
2081
2082 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 * Return the full name for a given resource identifier. This name is
2084 * a single string of the form "package:type/entry".
2085 *
2086 * @param resid The resource identifier whose name is to be retrieved.
2087 *
2088 * @return A string holding the name of the resource.
2089 *
2090 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
2091 *
2092 * @see #getResourcePackageName
2093 * @see #getResourceTypeName
2094 * @see #getResourceEntryName
2095 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002096 public String getResourceName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002097 return mResourcesImpl.getResourceName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002098 }
2099
2100 /**
2101 * Return the package name for a given resource identifier.
2102 *
2103 * @param resid The resource identifier whose package name is to be
2104 * retrieved.
2105 *
2106 * @return A string holding the package name of the resource.
2107 *
2108 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
2109 *
2110 * @see #getResourceName
2111 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002112 public String getResourcePackageName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002113 return mResourcesImpl.getResourcePackageName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
2115
2116 /**
2117 * Return the type name for a given resource identifier.
2118 *
2119 * @param resid The resource identifier whose type name is to be
2120 * retrieved.
2121 *
2122 * @return A string holding the type name of the resource.
2123 *
2124 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
2125 *
2126 * @see #getResourceName
2127 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002128 public String getResourceTypeName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002129 return mResourcesImpl.getResourceTypeName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130 }
Winson2f3669b2019-01-11 11:28:34 -08002131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 /**
2133 * Return the entry name for a given resource identifier.
Winson2f3669b2019-01-11 11:28:34 -08002134 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002135 * @param resid The resource identifier whose entry name is to be
2136 * retrieved.
Winson2f3669b2019-01-11 11:28:34 -08002137 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 * @return A string holding the entry name of the resource.
Winson2f3669b2019-01-11 11:28:34 -08002139 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
Winson2f3669b2019-01-11 11:28:34 -08002141 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 * @see #getResourceName
2143 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002144 public String getResourceEntryName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002145 return mResourcesImpl.getResourceEntryName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 }
Winson2f3669b2019-01-11 11:28:34 -08002147
2148 /**
2149 * Return formatted log of the last retrieved resource's resolution path.
2150 *
2151 * @return A string holding a formatted log of the steps taken to resolve the last resource.
2152 *
2153 * @throws NotFoundException Throws NotFoundException if there hasn't been a resource
2154 * resolved yet.
2155 *
2156 * @hide
2157 */
2158 public String getLastResourceResolution() throws NotFoundException {
2159 return mResourcesImpl.getLastResourceResolution();
2160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161
2162 /**
2163 * Parse a series of {@link android.R.styleable#Extra &lt;extra&gt;} tags from
2164 * an XML file. You call this when you are at the parent tag of the
Dianne Hackborndef15372010-08-15 12:43:52 -07002165 * 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 -08002166 * This will call {@link #parseBundleExtra} for each extra tag encountered.
2167 *
2168 * @param parser The parser from which to retrieve the extras.
2169 * @param outBundle A Bundle in which to place all parsed extras.
2170 * @throws XmlPullParserException
2171 * @throws IOException
2172 */
2173 public void parseBundleExtras(XmlResourceParser parser, Bundle outBundle)
2174 throws XmlPullParserException, IOException {
2175 int outerDepth = parser.getDepth();
2176 int type;
2177 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2178 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2179 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2180 continue;
2181 }
2182
2183 String nodeName = parser.getName();
2184 if (nodeName.equals("extra")) {
2185 parseBundleExtra("extra", parser, outBundle);
2186 XmlUtils.skipCurrentTag(parser);
2187
2188 } else {
2189 XmlUtils.skipCurrentTag(parser);
2190 }
2191 }
2192 }
2193
2194 /**
2195 * Parse a name/value pair out of an XML tag holding that data. The
2196 * AttributeSet must be holding the data defined by
2197 * {@link android.R.styleable#Extra}. The following value types are supported:
2198 * <ul>
2199 * <li> {@link TypedValue#TYPE_STRING}:
2200 * {@link Bundle#putCharSequence Bundle.putCharSequence()}
2201 * <li> {@link TypedValue#TYPE_INT_BOOLEAN}:
2202 * {@link Bundle#putCharSequence Bundle.putBoolean()}
2203 * <li> {@link TypedValue#TYPE_FIRST_INT}-{@link TypedValue#TYPE_LAST_INT}:
2204 * {@link Bundle#putCharSequence Bundle.putBoolean()}
2205 * <li> {@link TypedValue#TYPE_FLOAT}:
2206 * {@link Bundle#putCharSequence Bundle.putFloat()}
2207 * </ul>
2208 *
2209 * @param tagName The name of the tag these attributes come from; this is
2210 * only used for reporting error messages.
2211 * @param attrs The attributes from which to retrieve the name/value pair.
2212 * @param outBundle The Bundle in which to place the parsed value.
2213 * @throws XmlPullParserException If the attributes are not valid.
2214 */
2215 public void parseBundleExtra(String tagName, AttributeSet attrs,
2216 Bundle outBundle) throws XmlPullParserException {
2217 TypedArray sa = obtainAttributes(attrs,
2218 com.android.internal.R.styleable.Extra);
2219
2220 String name = sa.getString(
2221 com.android.internal.R.styleable.Extra_name);
2222 if (name == null) {
2223 sa.recycle();
2224 throw new XmlPullParserException("<" + tagName
2225 + "> requires an android:name attribute at "
2226 + attrs.getPositionDescription());
2227 }
2228
2229 TypedValue v = sa.peekValue(
2230 com.android.internal.R.styleable.Extra_value);
2231 if (v != null) {
2232 if (v.type == TypedValue.TYPE_STRING) {
2233 CharSequence cs = v.coerceToString();
2234 outBundle.putCharSequence(name, cs);
2235 } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
2236 outBundle.putBoolean(name, v.data != 0);
2237 } else if (v.type >= TypedValue.TYPE_FIRST_INT
2238 && v.type <= TypedValue.TYPE_LAST_INT) {
2239 outBundle.putInt(name, v.data);
2240 } else if (v.type == TypedValue.TYPE_FLOAT) {
2241 outBundle.putFloat(name, v.getFloat());
2242 } else {
2243 sa.recycle();
2244 throw new XmlPullParserException("<" + tagName
2245 + "> only supports string, integer, float, color, and boolean at "
2246 + attrs.getPositionDescription());
2247 }
2248 } else {
2249 sa.recycle();
2250 throw new XmlPullParserException("<" + tagName
2251 + "> requires an android:value or android:resource attribute at "
2252 + attrs.getPositionDescription());
2253 }
2254
2255 sa.recycle();
2256 }
2257
2258 /**
2259 * Retrieve underlying AssetManager storage for these resources.
2260 */
2261 public final AssetManager getAssets() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002262 return mResourcesImpl.getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 }
2264
2265 /**
2266 * Call this to remove all cached loaded layout resources from the
2267 * Resources object. Only intended for use with performance testing
2268 * tools.
2269 */
2270 public final void flushLayoutCache() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002271 mResourcesImpl.flushLayoutCache();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 }
2273
2274 /**
2275 * Start preloading of resource data using this Resources object. Only
2276 * for use by the zygote process for loading common system resources.
2277 * {@hide}
2278 */
2279 public final void startPreloading() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002280 mResourcesImpl.startPreloading();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 }
2282
2283 /**
2284 * Called by zygote when it is done preloading resources, to change back
2285 * to normal Resources operation.
2286 */
2287 public final void finishPreloading() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002288 mResourcesImpl.finishPreloading();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07002290
Romain Guy3b748a42013-04-17 18:54:38 -07002291 /**
2292 * @hide
2293 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002294 @UnsupportedAppUsage
Alan Viverette52b999f2014-03-24 18:00:26 -07002295 public LongSparseArray<ConstantState> getPreloadedDrawables() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002296 return mResourcesImpl.getPreloadedDrawables();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 }
2298
Alan Viverette10979612016-01-06 15:27:35 -05002299 /**
2300 * Loads an XML parser for the specified file.
2301 *
2302 * @param id the resource identifier for the file
2303 * @param type the type of resource (used for logging)
2304 * @return a parser for the specified XML file
2305 * @throws NotFoundException if the file could not be loaded
2306 */
2307 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002308 @UnsupportedAppUsage
Alan Viverette10979612016-01-06 15:27:35 -05002309 XmlResourceParser loadXmlResourceParser(@AnyRes int id, @NonNull String type)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002311 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05002312 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002313 final ResourcesImpl impl = mResourcesImpl;
2314 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 if (value.type == TypedValue.TYPE_STRING) {
Winson9947f1e2019-08-16 10:20:39 -07002316 return loadXmlResourceParser(value.string.toString(), id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 value.assetCookie, type);
2318 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05002319 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
2320 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
2321 } finally {
2322 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 }
2324 }
Alan Viverette10979612016-01-06 15:27:35 -05002325
2326 /**
2327 * Loads an XML parser for the specified file.
2328 *
2329 * @param file the path for the XML file to parse
2330 * @param id the resource identifier for the file
2331 * @param assetCookie the asset cookie for the file
2332 * @param type the type of resource (used for logging)
2333 * @return a parser for the specified XML file
2334 * @throws NotFoundException if the file could not be loaded
2335 */
2336 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002337 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002338 XmlResourceParser loadXmlResourceParser(String file, int id, int assetCookie,
2339 String type) throws NotFoundException {
Winson9947f1e2019-08-16 10:20:39 -07002340 ResourceLoader loader = findLoader(assetCookie);
2341 if (loader != null) {
2342 XmlResourceParser xml = loader.loadXmlResourceParser(file, id);
2343 if (xml != null) {
2344 return xml;
2345 }
2346 }
2347
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002348 return mResourcesImpl.loadXmlResourceParser(file, id, assetCookie, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 }
2350
Alan Viverette45c4bbb2015-01-05 14:59:19 -08002351 /**
Adam Lesinski082614c2016-03-04 14:33:47 -08002352 * Called by ConfigurationBoundResourceCacheTest.
2353 * @hide
2354 */
2355 @VisibleForTesting
2356 public int calcConfigChanges(Configuration config) {
2357 return mResourcesImpl.calcConfigChanges(config);
2358 }
2359
2360 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -08002361 * Obtains styled attributes from the theme, if available, or unstyled
2362 * resources if the theme is null.
2363 *
2364 * @hide
2365 */
2366 public static TypedArray obtainAttributes(
2367 Resources res, Theme theme, AttributeSet set, int[] attrs) {
2368 if (theme == null) {
2369 return res.obtainAttributes(set, attrs);
2370 }
2371 return theme.obtainStyledAttributes(set, attrs, 0, 0);
2372 }
Winson9947f1e2019-08-16 10:20:39 -07002373
2374 private ResourceLoader findLoader(int assetCookie) {
2375 ApkAssets[] apkAssetsArray = mResourcesImpl.getAssets().getApkAssets();
2376 int apkAssetsIndex = assetCookie - 1;
2377 if (apkAssetsIndex < apkAssetsArray.length && apkAssetsIndex >= 0) {
2378 ApkAssets apkAssets = apkAssetsArray[apkAssetsIndex];
2379 if (apkAssets.isForLoader()) {
2380 List<Pair<ResourceLoader, ResourcesProvider>> loaders;
2381 // Since we don't lock the entire resolution path anyways,
2382 // only lock here instead of entire method. The list is copied
2383 // and effectively a snapshot is used.
2384 synchronized (mResourceLoaderLock) {
2385 loaders = mResourceLoaderManager.getInternalList();
2386 }
2387
2388 if (!ArrayUtils.isEmpty(loaders)) {
2389 int size = loaders.size();
2390 for (int index = 0; index < size; index++) {
2391 Pair<ResourceLoader, ResourcesProvider> pair = loaders.get(index);
2392 if (pair.second.getApkAssets() == apkAssets) {
2393 return pair.first;
2394 }
2395 }
2396 }
2397 }
2398 }
2399
2400 return null;
2401 }
2402
2403 /**
2404 * @return copied list of loaders and providers previously added
2405 */
2406 @NonNull
2407 public List<Pair<ResourceLoader, ResourcesProvider>> getLoaders() {
2408 synchronized (mResourceLoaderLock) {
2409 return mResourceLoaderManager == null
2410 ? Collections.emptyList()
2411 : mResourceLoaderManager.getLoaders();
2412 }
2413 }
2414
2415 /**
2416 * Add a custom {@link ResourceLoader} which is added to the paths searched by
2417 * {@link AssetManager} when resolving a resource.
2418 *
2419 * Resources are resolved as if the loader was a resource overlay, meaning the latest
2420 * in the list, of equal or better config, is returned.
2421 *
2422 * {@link ResourcesProvider}s passed in here are not managed and a reference should be held
2423 * to remove, re-use, or close them when necessary.
2424 *
2425 * @param resourceLoader an interface used to resolve file paths for drawables/XML files;
2426 * a reference should be kept to remove the loader if necessary
2427 * @param resourcesProvider an .apk or .arsc file representation
2428 * @param index where to add the loader in the list
2429 * @throws IllegalArgumentException if the resourceLoader is already added
2430 * @throws IndexOutOfBoundsException if the index is invalid
2431 */
2432 public void addLoader(@NonNull ResourceLoader resourceLoader,
2433 @NonNull ResourcesProvider resourcesProvider, @IntRange(from = 0) int index) {
2434 synchronized (mResourceLoaderLock) {
2435 if (mResourceLoaderManager == null) {
2436 ResourcesManager.getInstance().registerForLoaders(this);
2437 mResourceLoaderManager = new ResourceLoaderManager(mResourcesImpl);
2438 }
2439
2440 mResourceLoaderManager.addLoader(resourceLoader, resourcesProvider, index);
2441 }
2442 }
2443
2444 /**
2445 * @see #addLoader(ResourceLoader, ResourcesProvider, int).
2446 *
2447 * Adds to the end of the list.
2448 *
2449 * @return index the loader was added at
2450 */
2451 public int addLoader(@NonNull ResourceLoader resourceLoader,
2452 @NonNull ResourcesProvider resourcesProvider) {
2453 synchronized (mResourceLoaderLock) {
2454 int index = getLoaders().size();
2455 addLoader(resourceLoader, resourcesProvider, index);
2456 return index;
2457 }
2458 }
2459
2460 /**
2461 * Remove a loader previously added by
2462 * {@link #addLoader(ResourceLoader, ResourcesProvider, int)}
2463 *
2464 * The caller maintains responsibility for holding a reference to the matching
2465 * {@link ResourcesProvider} and closing it after this method has been called.
2466 *
2467 * @param resourceLoader the same reference passed into [addLoader
2468 * @return the index the loader was at in the list, or -1 if the loader was not found
2469 */
2470 public int removeLoader(@NonNull ResourceLoader resourceLoader) {
2471 synchronized (mResourceLoaderLock) {
2472 if (mResourceLoaderManager == null) {
2473 return -1;
2474 }
2475
2476 return mResourceLoaderManager.removeLoader(resourceLoader);
2477 }
2478 }
2479
2480 /**
2481 * Swap the current set of loaders. Preferred to multiple remove/add calls as this doesn't
2482 * update the resource data structures after each modification.
2483 *
2484 * Set to null or an empty list to clear the set of loaders.
2485 *
2486 * The caller maintains responsibility for holding references to the added
2487 * {@link ResourcesProvider}s and closing them after this method has been called.
2488 *
2489 * @param resourceLoadersAndProviders a list of pairs to add
2490 */
2491 public void setLoaders(
2492 @Nullable List<Pair<ResourceLoader, ResourcesProvider>> resourceLoadersAndProviders) {
2493 synchronized (mResourceLoaderLock) {
2494 if (mResourceLoaderManager == null) {
2495 if (ArrayUtils.isEmpty(resourceLoadersAndProviders)) {
2496 return;
2497 }
2498
2499 ResourcesManager.getInstance().registerForLoaders(this);
2500 mResourceLoaderManager = new ResourceLoaderManager(mResourcesImpl);
2501 }
2502
2503 mResourceLoaderManager.setLoaders(resourceLoadersAndProviders);
2504 }
2505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506}