blob: cb809da3b8679553f7df18102ebd81a33e0571f3 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content.res;
18
Alan Viverette45c4bbb2015-01-05 14:59:19 -080019import android.animation.Animator;
20import android.animation.StateListAnimator;
Tor Norbye7b9c9122013-05-30 16:48:33 -070021import android.annotation.AnimRes;
ztenghuib5292562017-07-11 16:03:36 -070022import android.annotation.AnimatorRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070023import android.annotation.AnyRes;
24import android.annotation.ArrayRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070025import android.annotation.AttrRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070026import android.annotation.BoolRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070027import android.annotation.ColorInt;
Tor Norbye7b9c9122013-05-30 16:48:33 -070028import android.annotation.ColorRes;
29import android.annotation.DimenRes;
30import android.annotation.DrawableRes;
Clara Bayarried00bfd2017-01-20 14:58:21 +000031import android.annotation.FontRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070032import android.annotation.FractionRes;
33import android.annotation.IntegerRes;
34import android.annotation.LayoutRes;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080035import android.annotation.NonNull;
Alan Viverette3b5c4272014-05-20 13:20:42 -070036import android.annotation.Nullable;
Tor Norbye7b9c9122013-05-30 16:48:33 -070037import android.annotation.PluralsRes;
38import android.annotation.RawRes;
39import android.annotation.StringRes;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070040import android.annotation.StyleRes;
41import android.annotation.StyleableRes;
Tor Norbye7b9c9122013-05-30 16:48:33 -070042import android.annotation.XmlRes;
Artur Satayeve23a0eb2019-12-10 17:47:52 +000043import android.compat.annotation.UnsupportedAppUsage;
Dianne Hackbornebff8f92011-05-12 18:07:47 -070044import android.content.pm.ActivityInfo;
Alan Viverette9ad386b2017-01-26 14:00:20 -050045import android.content.pm.ActivityInfo.Config;
Ryan Mitchell4579c0a2020-01-08 16:29:11 -080046import android.content.res.loader.ResourcesLoader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.graphics.Movie;
Clara Bayarri18e9f9f2016-12-19 16:20:29 +000048import android.graphics.Typeface;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080049import android.graphics.drawable.Drawable;
Masanori Oginoc7d9d272010-07-10 12:10:41 +090050import android.graphics.drawable.Drawable.ConstantState;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070051import android.graphics.drawable.DrawableInflater;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070052import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.os.Bundle;
Ryan Mitchell4579c0a2020-01-08 16:29:11 -080054import android.util.ArraySet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.util.AttributeSet;
56import android.util.DisplayMetrics;
57import android.util.Log;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080058import android.util.LongSparseArray;
59import android.util.Pools.SynchronizedPool;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.util.TypedValue;
Adam Lesinski4ece3d62016-06-16 18:05:41 -070061import android.view.DisplayAdjustments;
Alan Viverette45c4bbb2015-01-05 14:59:19 -080062import android.view.ViewDebug;
Siva Velusamy0d857b92015-04-22 10:23:56 -070063import android.view.ViewHierarchyEncoder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
Ryan Mitchelle2723072020-02-11 15:51:29 -080065import com.android.internal.annotations.GuardedBy;
Adam Lesinski082614c2016-03-04 14:33:47 -080066import com.android.internal.annotations.VisibleForTesting;
Winson9947f1e2019-08-16 10:20:39 -070067import com.android.internal.util.ArrayUtils;
Roozbeh Pournader47571c72015-09-01 14:07:04 -070068import com.android.internal.util.GrowingArrayUtils;
69import com.android.internal.util.XmlUtils;
70
71import org.xmlpull.v1.XmlPullParser;
72import org.xmlpull.v1.XmlPullParserException;
73
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import java.io.IOException;
75import java.io.InputStream;
Adam Lesinski082614c2016-03-04 14:33:47 -080076import java.lang.ref.WeakReference;
77import java.util.ArrayList;
Winson9947f1e2019-08-16 10:20:39 -070078import java.util.Collections;
79import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080
81/**
82 * Class for accessing an application's resources. This sits on top of the
Scott Mainf4f05b82011-01-07 14:38:23 -080083 * asset manager of the application (accessible through {@link #getAssets}) and
84 * provides a high-level API for getting typed data from the assets.
85 *
86 * <p>The Android resource system keeps track of all non-code assets associated with an
87 * application. You can use this class to access your application's resources. You can generally
88 * acquire the {@link android.content.res.Resources} instance associated with your application
89 * with {@link android.content.Context#getResources getResources()}.</p>
90 *
91 * <p>The Android SDK tools compile your application's resources into the application binary
92 * at build time. To use a resource, you must install it correctly in the source tree (inside
93 * your project's {@code res/} directory) and build your application. As part of the build
94 * process, the SDK tools generate symbols for each resource, which you can use in your application
95 * code to access the resources.</p>
96 *
97 * <p>Using application resources makes it easy to update various characteristics of your
98 * application without modifying code, and&mdash;by providing sets of alternative
99 * resources&mdash;enables you to optimize your application for a variety of device configurations
100 * (such as for different languages and screen sizes). This is an important aspect of developing
101 * Android applications that are compatible on different types of devices.</p>
102 *
103 * <p>For more information about using resources, see the documentation about <a
104 * href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 */
106public class Resources {
Aurimas Liutikas83386232019-01-16 12:46:42 -0800107 /**
108 * The {@code null} resource ID. This denotes an invalid resource ID that is returned by the
109 * system when a resource is not found or the value is set to {@code @null} in XML.
110 */
111 public static final @AnyRes int ID_NULL = 0;
112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 static final String TAG = "Resources";
Alan Viverette562a6a82014-01-31 11:07:29 -0800114
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800115 private static final Object sSync = new Object();
Ryan Mitchelle2723072020-02-11 15:51:29 -0800116 private final Object mUpdateLock = new Object();
Fabrice Di Megliob9a13b82013-04-15 14:05:30 -0700117
Alan Viveretteedc46642014-02-01 01:43:16 -0800118 // Used by BridgeResources in layoutlib
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100119 @UnsupportedAppUsage
Alan Viveretteedc46642014-02-01 01:43:16 -0800120 static Resources mSystem = null;
121
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100122 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800123 private ResourcesImpl mResourcesImpl;
Alan Viverette4d07bc92015-11-16 10:19:12 -0500124
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800125 // Pool of TypedArrays targeted to this Resources object.
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100126 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800127 final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400129 /** Used to inflate drawable objects from XML. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100130 @UnsupportedAppUsage
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400131 private DrawableInflater mDrawableInflater;
132
Alan Viverette4d07bc92015-11-16 10:19:12 -0500133 /** Lock object used to protect access to {@link #mTmpValue}. */
134 private final Object mTmpValueLock = new Object();
135
136 /** Single-item pool used to minimize TypedValue allocations. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100137 @UnsupportedAppUsage
Alan Viverette562a6a82014-01-31 11:07:29 -0800138 private TypedValue mTmpValue = new TypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500139
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100140 @UnsupportedAppUsage
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400141 final ClassLoader mClassLoader;
Fabrice Di Megliob9a13b82013-04-15 14:05:30 -0700142
Ryan Mitchelle2723072020-02-11 15:51:29 -0800143 @GuardedBy("mUpdateLock")
Ryan Mitchell4579c0a2020-01-08 16:29:11 -0800144 private UpdateCallbacks mCallbacks = null;
Winson9947f1e2019-08-16 10:20:39 -0700145
Alan Viverette62599332014-04-01 14:57:39 -0700146 /**
Adam Lesinski082614c2016-03-04 14:33:47 -0800147 * WeakReferences to Themes that were constructed from this Resources object.
148 * We keep track of these in case our underlying implementation is changed, in which case
149 * the Themes must also get updated ThemeImpls.
150 */
151 private final ArrayList<WeakReference<Theme>> mThemeRefs = new ArrayList<>();
152
153 /**
Richard Uhlerdd6a0db2018-04-26 15:09:30 +0100154 * To avoid leaking WeakReferences to garbage collected Themes on the
155 * mThemeRefs list, we flush the list of stale references any time the
156 * mThemeRefNextFlushSize is reached.
157 */
158 private static final int MIN_THEME_REFS_FLUSH_SIZE = 32;
159 private int mThemeRefsNextFlushSize = MIN_THEME_REFS_FLUSH_SIZE;
160
Winson9947f1e2019-08-16 10:20:39 -0700161 private int mBaseApkAssetsSize;
162
Richard Uhlerdd6a0db2018-04-26 15:09:30 +0100163 /**
Alan Viverette62599332014-04-01 14:57:39 -0700164 * Returns the most appropriate default theme for the specified target SDK version.
Alan Viverette5effd7e2014-05-05 12:25:33 -0700165 * <ul>
166 * <li>Below API 11: Gingerbread
Alan Viverette4b2b6152016-06-08 11:45:15 -0400167 * <li>APIs 12 thru 14: Holo
168 * <li>APIs 15 thru 23: Device default dark
169 * <li>APIs 24 and above: Device default light with dark action bar
Alan Viverette5effd7e2014-05-05 12:25:33 -0700170 * </ul>
Alan Viverette62599332014-04-01 14:57:39 -0700171 *
172 * @param curTheme The current theme, or 0 if not specified.
173 * @param targetSdkVersion The target SDK version.
174 * @return A theme resource identifier
175 * @hide
176 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100177 @UnsupportedAppUsage
Alan Viverette5effd7e2014-05-05 12:25:33 -0700178 public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800179 return selectSystemTheme(curTheme, targetSdkVersion,
Alan Viverette5effd7e2014-05-05 12:25:33 -0700180 com.android.internal.R.style.Theme,
181 com.android.internal.R.style.Theme_Holo,
182 com.android.internal.R.style.Theme_DeviceDefault,
183 com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800184 }
Alan Viverette62599332014-04-01 14:57:39 -0700185
Alan Viverette5effd7e2014-05-05 12:25:33 -0700186 /** @hide */
187 public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo,
188 int dark, int deviceDefault) {
Aurimas Liutikasd8ebfef2019-01-16 12:46:42 -0800189 if (curTheme != ID_NULL) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800190 return curTheme;
191 }
Alan Viverette5effd7e2014-05-05 12:25:33 -0700192 if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
193 return orig;
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800194 }
Alan Viverette5effd7e2014-05-05 12:25:33 -0700195 if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
196 return holo;
197 }
Alan Viverette4b2b6152016-06-08 11:45:15 -0400198 if (targetSdkVersion < Build.VERSION_CODES.N) {
Alan Viverette5effd7e2014-05-05 12:25:33 -0700199 return dark;
200 }
201 return deviceDefault;
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800202 }
Alan Viverette62599332014-04-01 14:57:39 -0700203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800205 * Return a global shared Resources object that provides access to only
MÃ¥rten Kongstad371da732019-03-13 22:27:40 +0100206 * system resources (no application resources), is not configured for the
207 * current screen (can not use dimension units, does not change based on
208 * orientation, etc), and is not affected by Runtime Resource Overlay.
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400209 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800210 public static Resources getSystem() {
211 synchronized (sSync) {
212 Resources ret = mSystem;
213 if (ret == null) {
214 ret = new Resources();
215 mSystem = ret;
216 }
217 return ret;
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400218 }
Yigit Boyard422dc32014-09-25 12:23:35 -0700219 }
220
221 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 * This exception is thrown by the resource APIs when a requested resource
223 * can not be found.
224 */
225 public static class NotFoundException extends RuntimeException {
226 public NotFoundException() {
227 }
228
229 public NotFoundException(String name) {
230 super(name);
231 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500232
233 public NotFoundException(String name, Exception cause) {
234 super(name, cause);
235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 }
237
Ryan Mitchell4579c0a2020-01-08 16:29:11 -0800238 /** @hide */
239 public interface UpdateCallbacks extends ResourcesLoader.UpdateCallbacks {
240 /**
241 * Invoked when a {@link Resources} instance has a {@link ResourcesLoader} added, removed,
242 * or reordered.
243 *
244 * @param resources the instance being updated
245 * @param newLoaders the new set of loaders for the instance
246 */
247 void onLoadersChanged(Resources resources, List<ResourcesLoader> newLoaders);
248 }
249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 /**
251 * Create a new Resources object on top of an existing set of assets in an
252 * AssetManager.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800253 *
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -0700254 * @deprecated Resources should not be constructed by apps.
255 * See {@link android.content.Context#createConfigurationContext(Configuration)}.
256 *
Wale Ogunwale60454db2015-01-23 16:05:07 -0800257 * @param assets Previously created AssetManager.
258 * @param metrics Current display metrics to consider when
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 * selecting/computing resource values.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800260 * @param config Desired device configuration to consider when
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 * selecting/computing resource values (optional).
262 */
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -0700263 @Deprecated
Romain Guy5d911c32012-04-12 16:25:17 -0700264 public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800265 this(null);
Adam Lesinski8e8d2322016-06-24 12:29:16 -0700266 mResourcesImpl = new ResourcesImpl(assets, metrics, config, new DisplayAdjustments());
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700267 }
268
269 /**
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -0700270 * Creates a new Resources object with CompatibilityInfo.
Wale Ogunwale60454db2015-01-23 16:05:07 -0800271 *
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400272 * @param classLoader class loader for the package used to load custom
273 * resource classes, may be {@code null} to use system
274 * class loader
Mitsuru Oshima8169dae2009-04-28 18:12:09 -0700275 * @hide
276 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100277 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800278 public Resources(@Nullable ClassLoader classLoader) {
Alan Viverette02fc5fe2015-08-27 13:16:09 -0400279 mClassLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader;
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700280 }
281
282 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800283 * Only for creating the System resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100285 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800286 private Resources() {
287 this(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800289 final DisplayMetrics metrics = new DisplayMetrics();
290 metrics.setToDefaults();
291
292 final Configuration config = new Configuration();
293 config.setToDefaults();
294
295 mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
Adam Lesinski8e8d2322016-06-24 12:29:16 -0700296 new DisplayAdjustments());
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800297 }
298
299 /**
Adam Lesinski082614c2016-03-04 14:33:47 -0800300 * Set the underlying implementation (containing all the resources and caches)
301 * and updates all Theme references to new implementations as well.
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800302 * @hide
303 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100304 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800305 public void setImpl(ResourcesImpl impl) {
Adam Lesinski082614c2016-03-04 14:33:47 -0800306 if (impl == mResourcesImpl) {
307 return;
308 }
309
Winson9947f1e2019-08-16 10:20:39 -0700310 mBaseApkAssetsSize = ArrayUtils.size(impl.getAssets().getApkAssets());
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800311 mResourcesImpl = impl;
Adam Lesinski082614c2016-03-04 14:33:47 -0800312
313 // Create new ThemeImpls that are identical to the ones we have.
314 synchronized (mThemeRefs) {
315 final int count = mThemeRefs.size();
316 for (int i = 0; i < count; i++) {
317 WeakReference<Theme> weakThemeRef = mThemeRefs.get(i);
318 Theme theme = weakThemeRef != null ? weakThemeRef.get() : null;
319 if (theme != null) {
320 theme.setImpl(mResourcesImpl.newThemeImpl(theme.getKey()));
321 }
322 }
323 }
324 }
325
Ryan Mitchell4579c0a2020-01-08 16:29:11 -0800326 /** @hide */
327 public void setCallbacks(UpdateCallbacks callbacks) {
328 if (mCallbacks != null) {
329 throw new IllegalStateException("callback already registered");
330 }
331
332 mCallbacks = callbacks;
333 }
334
Adam Lesinski082614c2016-03-04 14:33:47 -0800335 /**
336 * @hide
337 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100338 @UnsupportedAppUsage
Adam Lesinski082614c2016-03-04 14:33:47 -0800339 public ResourcesImpl getImpl() {
340 return mResourcesImpl;
341 }
342
343 /**
344 * @hide
345 */
346 public ClassLoader getClassLoader() {
347 return mClassLoader;
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800348 }
349
350 /**
351 * @return the inflater used to create drawable objects
352 * @hide Pending API finalization.
353 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100354 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800355 public final DrawableInflater getDrawableInflater() {
356 if (mDrawableInflater == null) {
357 mDrawableInflater = new DrawableInflater(this, mClassLoader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800359 return mDrawableInflater;
360 }
361
362 /**
363 * Used by AnimatorInflater.
364 *
365 * @hide
366 */
367 public ConfigurationBoundResourceCache<Animator> getAnimatorCache() {
368 return mResourcesImpl.getAnimatorCache();
369 }
370
371 /**
372 * Used by AnimatorInflater.
373 *
374 * @hide
375 */
376 public ConfigurationBoundResourceCache<StateListAnimator> getStateListAnimatorCache() {
377 return mResourcesImpl.getStateListAnimatorCache();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 }
379
380 /**
381 * Return the string value associated with a particular resource ID. The
382 * returned object will be a String if this is a plain string; it will be
383 * some other type of CharSequence if it is styled.
384 * {@more}
385 *
386 * @param id The desired resource identifier, as generated by the aapt
387 * tool. This integer encodes the package, type, and resource
388 * entry. The value 0 is an invalid identifier.
389 *
390 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
391 *
392 * @return CharSequence The string data associated with the resource, plus
393 * possibly styled text information.
394 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800395 @NonNull public CharSequence getText(@StringRes int id) throws NotFoundException {
396 CharSequence res = mResourcesImpl.getAssets().getResourceText(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 if (res != null) {
398 return res;
399 }
400 throw new NotFoundException("String resource ID #0x"
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000401 + Integer.toHexString(id));
402 }
403
404 /**
405 * Return the Typeface value associated with a particular resource ID.
406 * {@more}
407 *
408 * @param id The desired resource identifier, as generated by the aapt
409 * tool. This integer encodes the package, type, and resource
410 * entry. The value 0 is an invalid identifier.
411 *
412 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
413 *
414 * @return Typeface The Typeface data associated with the resource.
415 */
Clara Bayarried00bfd2017-01-20 14:58:21 +0000416 @NonNull public Typeface getFont(@FontRes int id) throws NotFoundException {
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000417 final TypedValue value = obtainTempTypedValue();
418 try {
419 final ResourcesImpl impl = mResourcesImpl;
420 impl.getValue(id, value, true);
Clara Bayarried00bfd2017-01-20 14:58:21 +0000421 Typeface typeface = impl.loadFont(this, value, id);
Clara Bayarri18e9f9f2016-12-19 16:20:29 +0000422 if (typeface != null) {
423 return typeface;
424 }
425 } finally {
426 releaseTempTypedValue(value);
427 }
428 throw new NotFoundException("Font resource ID #0x"
429 + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 }
431
Clara Bayarried00bfd2017-01-20 14:58:21 +0000432 @NonNull
433 Typeface getFont(@NonNull TypedValue value, @FontRes int id) throws NotFoundException {
434 return mResourcesImpl.loadFont(this, value, id);
435 }
436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 /**
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000438 * @hide
439 */
Clara Bayarri2821eea2017-03-17 17:38:50 +0000440 public void preloadFonts(@ArrayRes int id) {
441 final TypedArray array = obtainTypedArray(id);
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000442 try {
Clara Bayarri2821eea2017-03-17 17:38:50 +0000443 final int size = array.length();
444 for (int i = 0; i < size; i++) {
445 array.getFont(i);
446 }
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000447 } finally {
Clara Bayarri2821eea2017-03-17 17:38:50 +0000448 array.recycle();
Clara Bayarri4b5a4d22017-01-27 20:15:45 +0000449 }
450 }
451
452 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800453 * Returns the character sequence necessary for grammatically correct pluralization
454 * of the given resource ID for the given quantity.
455 * Note that the character sequence is selected based solely on grammatical necessity,
456 * and that such rules differ between languages. Do not assume you know which string
457 * will be returned for a given quantity. See
458 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
459 * for more detail.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700460 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 * @param id The desired resource identifier, as generated by the aapt
462 * tool. This integer encodes the package, type, and resource
463 * entry. The value 0 is an invalid identifier.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700464 * @param quantity The number used to get the correct string for the current language's
465 * plural rules.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 *
467 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
468 *
469 * @return CharSequence The string data associated with the resource, plus
470 * possibly styled text information.
471 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800472 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700473 public CharSequence getQuantityText(@PluralsRes int id, int quantity)
474 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800475 return mResourcesImpl.getQuantityText(id, quantity);
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700476 }
477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 /**
479 * Return the string value associated with a particular resource ID. It
480 * will be stripped of any styled text information.
481 * {@more}
482 *
483 * @param id The desired resource identifier, as generated by the aapt
484 * tool. This integer encodes the package, type, and resource
485 * entry. The value 0 is an invalid identifier.
486 *
487 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
488 *
489 * @return String The string data associated with the resource,
Alan Viveretteb4004df2015-04-29 16:55:42 -0700490 * stripped of styled text information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 */
Alan Viveretteb4004df2015-04-29 16:55:42 -0700492 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700493 public String getString(@StringRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800494 return getText(id).toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 }
496
497
498 /**
499 * Return the string value associated with a particular resource ID,
500 * substituting the format arguments as defined in {@link java.util.Formatter}
501 * and {@link java.lang.String#format}. It will be stripped of any styled text
502 * information.
503 * {@more}
504 *
505 * @param id The desired resource identifier, as generated by the aapt
506 * tool. This integer encodes the package, type, and resource
507 * entry. The value 0 is an invalid identifier.
508 *
509 * @param formatArgs The format arguments that will be used for substitution.
510 *
511 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
512 *
513 * @return String The string data associated with the resource,
Alan Viveretteb4004df2015-04-29 16:55:42 -0700514 * stripped of styled text information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 */
Alan Viveretteb4004df2015-04-29 16:55:42 -0700516 @NonNull
517 public String getString(@StringRes int id, Object... formatArgs) throws NotFoundException {
518 final String raw = getString(id);
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800519 return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
520 formatArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 }
522
523 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800524 * Formats the string necessary for grammatically correct pluralization
525 * of the given resource ID for the given quantity, using the given arguments.
526 * Note that the string is selected based solely on grammatical necessity,
527 * and that such rules differ between languages. Do not assume you know which string
528 * will be returned for a given quantity. See
529 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
530 * for more detail.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 *
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800532 * <p>Substitution of format arguments works as if using
533 * {@link java.util.Formatter} and {@link java.lang.String#format}.
534 * The resulting string will be stripped of any styled text information.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700535 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 * @param id The desired resource identifier, as generated by the aapt
537 * tool. This integer encodes the package, type, and resource
538 * entry. The value 0 is an invalid identifier.
539 * @param quantity The number used to get the correct string for the current language's
540 * plural rules.
541 * @param formatArgs The format arguments that will be used for substitution.
542 *
543 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
544 *
545 * @return String The string data associated with the resource,
546 * stripped of styled text information.
547 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800548 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700549 public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 throws NotFoundException {
551 String raw = getQuantityText(id, quantity).toString();
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800552 return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
553 formatArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 }
555
556 /**
Elliott Hughes95d5ab32013-03-08 11:26:57 -0800557 * Returns the string necessary for grammatically correct pluralization
558 * of the given resource ID for the given quantity.
559 * Note that the string is selected based solely on grammatical necessity,
560 * and that such rules differ between languages. Do not assume you know which string
561 * will be returned for a given quantity. See
562 * <a href="{@docRoot}guide/topics/resources/string-resource.html#Plurals">String Resources</a>
563 * for more detail.
Elliott Hughes1ad636c2010-07-01 16:51:48 -0700564 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 * @param id The desired resource identifier, as generated by the aapt
566 * tool. This integer encodes the package, type, and resource
567 * entry. The value 0 is an invalid identifier.
568 * @param quantity The number used to get the correct string for the current language's
569 * plural rules.
570 *
571 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
572 *
573 * @return String The string data associated with the resource,
574 * stripped of styled text information.
575 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800576 @NonNull
577 public String getQuantityString(@PluralsRes int id, int quantity) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 return getQuantityText(id, quantity).toString();
579 }
580
581 /**
582 * Return the string value associated with a particular resource ID. The
583 * returned object will be a String if this is a plain string; it will be
584 * some other type of CharSequence if it is styled.
585 *
586 * @param id The desired resource identifier, as generated by the aapt
587 * tool. This integer encodes the package, type, and resource
588 * entry. The value 0 is an invalid identifier.
589 *
590 * @param def The default CharSequence to return.
591 *
592 * @return CharSequence The string data associated with the resource, plus
593 * possibly styled text information, or def if id is 0 or not found.
594 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700595 public CharSequence getText(@StringRes int id, CharSequence def) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800596 CharSequence res = id != 0 ? mResourcesImpl.getAssets().getResourceText(id) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 return res != null ? res : def;
598 }
599
600 /**
601 * Return the styled text array associated with a particular resource ID.
602 *
603 * @param id The desired resource identifier, as generated by the aapt
604 * tool. This integer encodes the package, type, and resource
605 * entry. The value 0 is an invalid identifier.
606 *
607 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
608 *
609 * @return The styled text array associated with the resource.
610 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800611 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700612 public CharSequence[] getTextArray(@ArrayRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800613 CharSequence[] res = mResourcesImpl.getAssets().getResourceTextArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 if (res != null) {
615 return res;
616 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800617 throw new NotFoundException("Text array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 }
619
620 /**
621 * Return the string array associated with a particular resource ID.
622 *
623 * @param id The desired resource identifier, as generated by the aapt
624 * tool. This integer encodes the package, type, and resource
625 * entry. The value 0 is an invalid identifier.
626 *
627 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
628 *
629 * @return The string array associated with the resource.
630 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800631 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700632 public String[] getStringArray(@ArrayRes int id)
633 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800634 String[] res = mResourcesImpl.getAssets().getResourceStringArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 if (res != null) {
636 return res;
637 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800638 throw new NotFoundException("String array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 }
640
641 /**
642 * Return the int array associated with a particular resource ID.
643 *
644 * @param id The desired resource identifier, as generated by the aapt
645 * tool. This integer encodes the package, type, and resource
646 * entry. The value 0 is an invalid identifier.
647 *
648 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
649 *
650 * @return The int array associated with the resource.
651 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800652 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -0700653 public int[] getIntArray(@ArrayRes int id) throws NotFoundException {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800654 int[] res = mResourcesImpl.getAssets().getResourceIntArray(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 if (res != null) {
656 return res;
657 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800658 throw new NotFoundException("Int array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 }
660
661 /**
662 * Return an array of heterogeneous values.
663 *
664 * @param id The desired resource identifier, as generated by the aapt
665 * tool. This integer encodes the package, type, and resource
666 * entry. The value 0 is an invalid identifier.
667 *
668 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
669 *
670 * @return Returns a TypedArray holding an array of the array values.
671 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
672 * when done with it.
673 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800674 @NonNull
675 public TypedArray obtainTypedArray(@ArrayRes int id) throws NotFoundException {
676 final ResourcesImpl impl = mResourcesImpl;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800677 int len = impl.getAssets().getResourceArraySize(id);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 if (len < 0) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800679 throw new NotFoundException("Array resource ID #0x" + Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 }
681
Alan Viverette52b999f2014-03-24 18:00:26 -0700682 TypedArray array = TypedArray.obtain(this, len);
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800683 array.mLength = impl.getAssets().getResourceArray(id, array.mData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 array.mIndices[0] = 0;
685
686 return array;
687 }
688
689 /**
690 * Retrieve a dimensional for a particular resource ID. Unit
691 * conversions are based on the current {@link DisplayMetrics} associated
692 * with the resources.
693 *
694 * @param id The desired resource identifier, as generated by the aapt
695 * tool. This integer encodes the package, type, and resource
696 * entry. The value 0 is an invalid identifier.
697 *
Danny Epstein4ffbd472018-06-29 16:21:03 -0700698 * @return Resource dimension value multiplied by the appropriate metric to convert to pixels.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 *
700 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
701 *
702 * @see #getDimensionPixelOffset
703 * @see #getDimensionPixelSize
704 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700705 public float getDimension(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800706 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500707 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800708 final ResourcesImpl impl = mResourcesImpl;
709 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800711 return TypedValue.complexToDimension(value.data, impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500713 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
714 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
715 } finally {
716 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 }
718 }
719
720 /**
721 * Retrieve a dimensional for a particular resource ID for use
722 * as an offset in raw pixels. This is the same as
723 * {@link #getDimension}, except the returned value is converted to
724 * integer pixels for you. An offset conversion involves simply
725 * truncating the base value to an integer.
726 *
727 * @param id The desired resource identifier, as generated by the aapt
728 * tool. This integer encodes the package, type, and resource
729 * entry. The value 0 is an invalid identifier.
730 *
731 * @return Resource dimension value multiplied by the appropriate
732 * metric and truncated to integer pixels.
733 *
734 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
735 *
736 * @see #getDimension
737 * @see #getDimensionPixelSize
738 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700739 public int getDimensionPixelOffset(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800740 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500741 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800742 final ResourcesImpl impl = mResourcesImpl;
743 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800745 return TypedValue.complexToDimensionPixelOffset(value.data,
746 impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500748 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
749 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
750 } finally {
751 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 }
753 }
754
755 /**
756 * Retrieve a dimensional for a particular resource ID for use
757 * as a size in raw pixels. This is the same as
758 * {@link #getDimension}, except the returned value is converted to
759 * integer pixels for use as a size. A size conversion involves
760 * rounding the base value, and ensuring that a non-zero base value
761 * is at least one pixel in size.
762 *
763 * @param id The desired resource identifier, as generated by the aapt
764 * tool. This integer encodes the package, type, and resource
765 * entry. The value 0 is an invalid identifier.
766 *
767 * @return Resource dimension value multiplied by the appropriate
768 * metric and truncated to integer pixels.
769 *
770 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
771 *
772 * @see #getDimension
773 * @see #getDimensionPixelOffset
774 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700775 public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800776 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500777 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800778 final ResourcesImpl impl = mResourcesImpl;
779 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 if (value.type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800781 return TypedValue.complexToDimensionPixelSize(value.data, impl.getDisplayMetrics());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500783 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
784 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
785 } finally {
786 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 }
788 }
789
790 /**
791 * Retrieve a fractional unit for a particular resource ID.
792 *
793 * @param id The desired resource identifier, as generated by the aapt
794 * tool. This integer encodes the package, type, and resource
795 * entry. The value 0 is an invalid identifier.
796 * @param base The base value of this fraction. In other words, a
797 * standard fraction is multiplied by this value.
798 * @param pbase The parent base value of this fraction. In other
799 * words, a parent fraction (nn%p) is multiplied by this
800 * value.
801 *
802 * @return Attribute fractional value multiplied by the appropriate
803 * base value.
804 *
805 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
806 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700807 public float getFraction(@FractionRes int id, int base, int pbase) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800808 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500809 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800810 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 if (value.type == TypedValue.TYPE_FRACTION) {
812 return TypedValue.complexToFraction(value.data, base, pbase);
813 }
Alan Viverette4d07bc92015-11-16 10:19:12 -0500814 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
815 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
816 } finally {
817 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818 }
819 }
820
821 /**
822 * Return a drawable object associated with a particular resource ID.
823 * Various types of objects will be returned depending on the underlying
824 * resource -- for example, a solid color, PNG image, scalable image, etc.
825 * The Drawable API hides these implementation details.
Dianne Hackbornfb5c3db2012-05-18 15:24:24 -0700826 *
827 * <p class="note"><strong>Note:</strong> Prior to
828 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN}, this function
829 * would not correctly retrieve the final configuration density when
830 * the resource ID passed here is an alias to another Drawable resource.
831 * This means that if the density configuration of the alias resource
832 * is different than the actual resource, the density of the returned
Alan Viverette952802e2016-04-04 15:33:41 -0400833 * Drawable would be incorrect, resulting in bad scaling. To work
834 * around this, you can instead manually resolve the aliased reference
835 * by using {@link #getValue(int, TypedValue, boolean)} and passing
836 * {@code true} for {@code resolveRefs}. The resulting
837 * {@link TypedValue#resourceId} value may be passed to this method.</p>
Dianne Hackbornfb5c3db2012-05-18 15:24:24 -0700838 *
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700839 * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use
840 * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)}
841 * or {@link #getDrawable(int, Theme)} passing the desired theme.</p>
842 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 * @param id The desired resource identifier, as generated by the aapt
844 * tool. This integer encodes the package, type, and resource
845 * entry. The value 0 is an invalid identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 * @return Drawable An object that can be used to draw this resource.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800847 * @throws NotFoundException Throws NotFoundException if the given ID does
848 * not exist.
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700849 * @see #getDrawable(int, Theme)
Alan Viverettec10e3962014-12-02 14:58:08 -0800850 * @deprecated Use {@link #getDrawable(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 */
Alan Viverettec10e3962014-12-02 14:58:08 -0800852 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700853 public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
Alan Viverette34a14f962014-08-15 16:13:15 -0700854 final Drawable d = getDrawable(id, null);
Alan Viverette7e0aaae2014-11-24 11:27:09 -0800855 if (d != null && d.canApplyTheme()) {
Alan Viverette34a14f962014-08-15 16:13:15 -0700856 Log.w(TAG, "Drawable " + getResourceName(id) + " has unresolved theme "
857 + "attributes! Consider using Resources.getDrawable(int, Theme) or "
858 + "Context.getDrawable(int).", new RuntimeException());
859 }
860 return d;
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800861 }
862
863 /**
864 * Return a drawable object associated with a particular resource ID and
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700865 * styled for the specified theme. Various types of objects will be
866 * returned depending on the underlying resource -- for example, a solid
867 * color, PNG image, scalable image, etc.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800868 *
869 * @param id The desired resource identifier, as generated by the aapt
870 * tool. This integer encodes the package, type, and resource
871 * entry. The value 0 is an invalid identifier.
Alan Viverette3b5c4272014-05-20 13:20:42 -0700872 * @param theme The theme used to style the drawable attributes, may be {@code null}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800873 * @return Drawable An object that can be used to draw this resource.
874 * @throws NotFoundException Throws NotFoundException if the given ID does
875 * not exist.
876 */
Alan Viverette4d07bc92015-11-16 10:19:12 -0500877 public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
878 throws NotFoundException {
Adam Lesinski50954d22017-04-14 18:41:52 -0700879 return getDrawableForDensity(id, 0, theme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 }
881
882 /**
Kenny Root55fc8502010-10-28 14:47:01 -0700883 * Return a drawable object associated with a particular resource ID for the
884 * given screen density in DPI. This will set the drawable's density to be
885 * the device's density multiplied by the ratio of actual drawable density
886 * to requested density. This allows the drawable to be scaled up to the
887 * correct size if needed. Various types of objects will be returned
888 * depending on the underlying resource -- for example, a solid color, PNG
889 * image, scalable image, etc. The Drawable API hides these implementation
890 * details.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800891 *
Alan Viverette6dbe51b2014-06-02 16:39:04 -0700892 * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use
893 * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)}
894 * or {@link #getDrawableForDensity(int, int, Theme)} passing the desired
895 * theme.</p>
896 *
Kenny Root55fc8502010-10-28 14:47:01 -0700897 * @param id The desired resource identifier, as generated by the aapt tool.
898 * This integer encodes the package, type, and resource entry.
899 * The value 0 is an invalid identifier.
900 * @param density the desired screen density indicated by the resource as
Adam Lesinski50954d22017-04-14 18:41:52 -0700901 * found in {@link DisplayMetrics}. A value of 0 means to use the
902 * density returned from {@link #getConfiguration()}.
903 * This is equivalent to calling {@link #getDrawable(int)}.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800904 * @return Drawable An object that can be used to draw this resource.
Kenny Root55fc8502010-10-28 14:47:01 -0700905 * @throws NotFoundException Throws NotFoundException if the given ID does
906 * not exist.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800907 * @see #getDrawableForDensity(int, int, Theme)
Alan Viverettea6f8b2c2014-12-02 15:26:33 -0800908 * @deprecated Use {@link #getDrawableForDensity(int, int, Theme)} instead.
Kenny Root55fc8502010-10-28 14:47:01 -0700909 */
Chris Craik1194b0b2018-03-23 13:36:24 -0700910 @Nullable
Alan Viverettea6f8b2c2014-12-02 15:26:33 -0800911 @Deprecated
Alan Viverette4d07bc92015-11-16 10:19:12 -0500912 public Drawable getDrawableForDensity(@DrawableRes int id, int density)
913 throws NotFoundException {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800914 return getDrawableForDensity(id, density, null);
915 }
916
917 /**
918 * Return a drawable object associated with a particular resource ID for the
919 * given screen density in DPI and styled for the specified theme.
920 *
921 * @param id The desired resource identifier, as generated by the aapt tool.
922 * This integer encodes the package, type, and resource entry.
923 * The value 0 is an invalid identifier.
924 * @param density The desired screen density indicated by the resource as
Adam Lesinski50954d22017-04-14 18:41:52 -0700925 * found in {@link DisplayMetrics}. A value of 0 means to use the
926 * density returned from {@link #getConfiguration()}.
927 * This is equivalent to calling {@link #getDrawable(int, Theme)}.
Chris Craik1194b0b2018-03-23 13:36:24 -0700928 * @param theme The theme used to style the drawable attributes, may be {@code null} if the
929 * drawable cannot be decoded.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800930 * @return Drawable An object that can be used to draw this resource.
931 * @throws NotFoundException Throws NotFoundException if the given ID does
Chris Craik1194b0b2018-03-23 13:36:24 -0700932 * not exist.
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800933 */
Chris Craik1194b0b2018-03-23 13:36:24 -0700934 @Nullable
Tor Norbye7b9c9122013-05-30 16:48:33 -0700935 public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800936 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -0500937 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800938 final ResourcesImpl impl = mResourcesImpl;
939 impl.getValueForDensity(id, density, value, true);
Winson9947f1e2019-08-16 10:20:39 -0700940 return loadDrawable(value, id, density, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -0500941 } finally {
942 releaseTempTypedValue(value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -0800943 }
Kenny Root55fc8502010-10-28 14:47:01 -0700944 }
945
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800946 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100947 @UnsupportedAppUsage
Adam Lesinski50954d22017-04-14 18:41:52 -0700948 Drawable loadDrawable(@NonNull TypedValue value, int id, int density, @Nullable Theme theme)
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800949 throws NotFoundException {
Adam Lesinski50954d22017-04-14 18:41:52 -0700950 return mResourcesImpl.loadDrawable(this, value, id, density, theme);
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800951 }
952
Kenny Root55fc8502010-10-28 14:47:01 -0700953 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 * Return a movie object associated with the particular resource ID.
955 * @param id The desired resource identifier, as generated by the aapt
956 * tool. This integer encodes the package, type, and resource
957 * entry. The value 0 is an invalid identifier.
958 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
Aurimas Liutikasf0764b52018-08-22 12:55:04 -0700959 *
960 * @deprecated Prefer {@link android.graphics.drawable.AnimatedImageDrawable}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 */
Aurimas Liutikasf0764b52018-08-22 12:55:04 -0700962 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700963 public Movie getMovie(@RawRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800964 final InputStream is = openRawResource(id);
965 final Movie movie = Movie.decodeStream(is);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 try {
967 is.close();
Adam Lesinskifb302cc2016-02-29 16:50:38 -0800968 } catch (IOException e) {
969 // No one cares.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 }
971 return movie;
972 }
973
974 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800975 * Returns a color integer associated with a particular resource ID. If the
976 * resource holds a complex {@link ColorStateList}, then the default color
977 * from the set is returned.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 *
979 * @param id The desired resource identifier, as generated by the aapt
980 * tool. This integer encodes the package, type, and resource
981 * entry. The value 0 is an invalid identifier.
982 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800983 * @throws NotFoundException Throws NotFoundException if the given ID does
984 * not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800986 * @return A single color value in the form 0xAARRGGBB.
987 * @deprecated Use {@link #getColor(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 */
Tor Norbye80756e32015-03-02 09:39:27 -0800989 @ColorInt
Alan Viverette4a357cd2015-03-18 18:37:18 -0700990 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -0700991 public int getColor(@ColorRes int id) throws NotFoundException {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800992 return getColor(id, null);
993 }
994
995 /**
996 * Returns a themed color integer associated with a particular resource ID.
997 * If the resource holds a complex {@link ColorStateList}, then the default
998 * color from the set is returned.
999 *
1000 * @param id The desired resource identifier, as generated by the aapt
1001 * tool. This integer encodes the package, type, and resource
1002 * entry. The value 0 is an invalid identifier.
1003 * @param theme The theme used to style the color attributes, may be
1004 * {@code null}.
1005 *
1006 * @throws NotFoundException Throws NotFoundException if the given ID does
1007 * not exist.
1008 *
1009 * @return A single color value in the form 0xAARRGGBB.
1010 */
Tor Norbye80756e32015-03-02 09:39:27 -08001011 @ColorInt
Tor Norbye7b9c9122013-05-30 16:48:33 -07001012 public int getColor(@ColorRes int id, @Nullable Theme theme) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001013 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001014 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001015 final ResourcesImpl impl = mResourcesImpl;
1016 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001018 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 return value.data;
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001020 } else if (value.type != TypedValue.TYPE_STRING) {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001021 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1022 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001024
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001025 final ColorStateList csl = impl.loadColorStateList(this, value, id, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -05001026 return csl.getDefaultColor();
1027 } finally {
1028 releaseTempTypedValue(value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 }
1031
1032 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001033 * Returns a color state list associated with a particular resource ID. The
1034 * resource may contain either a single raw color value or a complex
1035 * {@link ColorStateList} holding multiple possible colors.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 *
1037 * @param id The desired resource identifier of a {@link ColorStateList},
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001038 * as generated by the aapt tool. This integer encodes the
1039 * package, type, and resource entry. The value 0 is an invalid
1040 * identifier.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001042 * @throws NotFoundException Throws NotFoundException if the given ID does
1043 * not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 *
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001045 * @return A ColorStateList object containing either a single solid color
1046 * or multiple colors that can be selected based on a state.
1047 * @deprecated Use {@link #getColorStateList(int, Theme)} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 */
Chris Craikceb26932018-02-01 15:51:34 -08001049 @NonNull
Alan Viverette4a357cd2015-03-18 18:37:18 -07001050 @Deprecated
Tor Norbye7b9c9122013-05-30 16:48:33 -07001051 public ColorStateList getColorStateList(@ColorRes int id) throws NotFoundException {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001052 final ColorStateList csl = getColorStateList(id, null);
1053 if (csl != null && csl.canApplyTheme()) {
1054 Log.w(TAG, "ColorStateList " + getResourceName(id) + " has "
1055 + "unresolved theme attributes! Consider using "
1056 + "Resources.getColorStateList(int, Theme) or "
1057 + "Context.getColorStateList(int).", new RuntimeException());
1058 }
1059 return csl;
1060 }
1061
1062 /**
1063 * Returns a themed color state list associated with a particular resource
1064 * ID. The resource may contain either a single raw color value or a
1065 * complex {@link ColorStateList} holding multiple possible colors.
1066 *
1067 * @param id The desired resource identifier of a {@link ColorStateList},
1068 * as generated by the aapt tool. This integer encodes the
1069 * package, type, and resource entry. The value 0 is an invalid
1070 * identifier.
1071 * @param theme The theme used to style the color attributes, may be
1072 * {@code null}.
1073 *
1074 * @throws NotFoundException Throws NotFoundException if the given ID does
1075 * not exist.
1076 *
1077 * @return A themed ColorStateList object containing either a single solid
1078 * color or multiple colors that can be selected based on a state.
1079 */
Chris Craikceb26932018-02-01 15:51:34 -08001080 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001081 public ColorStateList getColorStateList(@ColorRes int id, @Nullable Theme theme)
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001082 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001083 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001084 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001085 final ResourcesImpl impl = mResourcesImpl;
1086 impl.getValue(id, value, true);
1087 return impl.loadColorStateList(this, value, id, theme);
Alan Viverette4d07bc92015-11-16 10:19:12 -05001088 } finally {
1089 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001090 }
1091 }
1092
Chris Craikceb26932018-02-01 15:51:34 -08001093 @NonNull
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001094 ColorStateList loadColorStateList(@NonNull TypedValue value, int id, @Nullable Theme theme)
1095 throws NotFoundException {
1096 return mResourcesImpl.loadColorStateList(this, value, id, theme);
1097 }
1098
Teng-Hui Zhue03c4692016-03-17 10:38:43 -07001099 /**
1100 * @hide
1101 */
Chris Craikceb26932018-02-01 15:51:34 -08001102 @NonNull
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001103 public ComplexColor loadComplexColor(@NonNull TypedValue value, int id, @Nullable Theme theme) {
1104 return mResourcesImpl.loadComplexColor(this, value, id, theme);
1105 }
1106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 /**
1108 * Return a boolean associated with a particular resource ID. This can be
1109 * used with any integral resource value, and will return true if it is
1110 * non-zero.
1111 *
1112 * @param id The desired resource identifier, as generated by the aapt
1113 * tool. This integer encodes the package, type, and resource
1114 * entry. The value 0 is an invalid identifier.
1115 *
1116 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1117 *
1118 * @return Returns the boolean value contained in the resource.
1119 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001120 public boolean getBoolean(@BoolRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001121 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001122 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001123 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette4d07bc92015-11-16 10:19:12 -05001125 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 return value.data != 0;
1127 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001128 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1129 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1130 } finally {
1131 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 }
1133 }
1134
1135 /**
1136 * Return an integer associated with a particular resource ID.
1137 *
1138 * @param id The desired resource identifier, as generated by the aapt
1139 * tool. This integer encodes the package, type, and resource
1140 * entry. The value 0 is an invalid identifier.
1141 *
1142 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1143 *
1144 * @return Returns the integer value contained in the resource.
1145 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001146 public int getInteger(@IntegerRes int id) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001147 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001148 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001149 mResourcesImpl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 if (value.type >= TypedValue.TYPE_FIRST_INT
Alan Viverette4d07bc92015-11-16 10:19:12 -05001151 && value.type <= TypedValue.TYPE_LAST_INT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 return value.data;
1153 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001154 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1155 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1156 } finally {
1157 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 }
1159 }
1160
1161 /**
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001162 * Retrieve a floating-point value for a particular resource ID.
1163 *
1164 * @param id The desired resource identifier, as generated by the aapt
1165 * tool. This integer encodes the package, type, and resource
1166 * entry. The value 0 is an invalid identifier.
1167 *
1168 * @return Returns the floating-point value contained in the resource.
1169 *
1170 * @throws NotFoundException Throws NotFoundException if the given ID does
1171 * not exist or is not a floating-point value.
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001172 */
Jake Wharton32365b92018-09-07 16:09:21 -04001173 public float getFloat(@DimenRes int id) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001174 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05001175 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001176 mResourcesImpl.getValue(id, value, true);
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001177 if (value.type == TypedValue.TYPE_FLOAT) {
1178 return value.getFloat();
1179 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001180 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
1181 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
1182 } finally {
1183 releaseTempTypedValue(value);
Alan Viveretteb1e1dbf2014-08-07 17:17:43 -07001184 }
1185 }
1186
1187 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 * Return an XmlResourceParser through which you can read a view layout
1189 * description for the given resource ID. This parser has limited
1190 * functionality -- in particular, you can't change its input, and only
1191 * the high-level events are available.
1192 *
1193 * <p>This function is really a simple wrapper for calling
1194 * {@link #getXml} with a layout resource.
1195 *
1196 * @param id The desired resource identifier, as generated by the aapt
1197 * tool. This integer encodes the package, type, and resource
1198 * entry. The value 0 is an invalid identifier.
1199 *
1200 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1201 *
1202 * @return A new parser object through which you can read
1203 * the XML data.
1204 *
1205 * @see #getXml
1206 */
Chris Craikceb26932018-02-01 15:51:34 -08001207 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001208 public XmlResourceParser getLayout(@LayoutRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 return loadXmlResourceParser(id, "layout");
1210 }
1211
1212 /**
1213 * Return an XmlResourceParser through which you can read an animation
1214 * description for the given resource ID. This parser has limited
1215 * functionality -- in particular, you can't change its input, and only
1216 * the high-level events are available.
1217 *
1218 * <p>This function is really a simple wrapper for calling
1219 * {@link #getXml} with an animation resource.
1220 *
1221 * @param id The desired resource identifier, as generated by the aapt
1222 * tool. This integer encodes the package, type, and resource
1223 * entry. The value 0 is an invalid identifier.
1224 *
1225 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1226 *
1227 * @return A new parser object through which you can read
1228 * the XML data.
1229 *
1230 * @see #getXml
1231 */
Chris Craikceb26932018-02-01 15:51:34 -08001232 @NonNull
ztenghuib5292562017-07-11 16:03:36 -07001233 public XmlResourceParser getAnimation(@AnimatorRes @AnimRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 return loadXmlResourceParser(id, "anim");
1235 }
1236
1237 /**
1238 * Return an XmlResourceParser through which you can read a generic XML
1239 * resource for the given resource ID.
1240 *
1241 * <p>The XmlPullParser implementation returned here has some limited
1242 * functionality. In particular, you can't change its input, and only
1243 * high-level parsing events are available (since the document was
1244 * pre-parsed for you at build time, which involved merging text and
1245 * stripping comments).
1246 *
1247 * @param id The desired resource identifier, as generated by the aapt
1248 * tool. This integer encodes the package, type, and resource
1249 * entry. The value 0 is an invalid identifier.
1250 *
1251 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1252 *
1253 * @return A new parser object through which you can read
1254 * the XML data.
1255 *
1256 * @see android.util.AttributeSet
1257 */
Chris Craikceb26932018-02-01 15:51:34 -08001258 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001259 public XmlResourceParser getXml(@XmlRes int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 return loadXmlResourceParser(id, "xml");
1261 }
1262
1263 /**
1264 * Open a data stream for reading a raw resource. This can only be used
1265 * with resources whose value is the name of an asset files -- that is, it can be
1266 * used to open drawable, sound, and raw resources; it will fail on string
1267 * and color resources.
1268 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001269 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 *
1271 * @return InputStream Access to the resource data.
1272 *
1273 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 */
Chris Craikceb26932018-02-01 15:51:34 -08001275 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001276 public InputStream openRawResource(@RawRes int id) throws NotFoundException {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001277 final TypedValue value = obtainTempTypedValue();
1278 try {
1279 return openRawResource(id, value);
1280 } finally {
1281 releaseTempTypedValue(value);
1282 }
1283 }
1284
1285 /**
Alan Viverette4d07bc92015-11-16 10:19:12 -05001286 * Returns a TypedValue suitable for temporary use. The obtained TypedValue
1287 * should be released using {@link #releaseTempTypedValue(TypedValue)}.
1288 *
1289 * @return a typed value suitable for temporary use
1290 */
1291 private TypedValue obtainTempTypedValue() {
1292 TypedValue tmpValue = null;
1293 synchronized (mTmpValueLock) {
1294 if (mTmpValue != null) {
1295 tmpValue = mTmpValue;
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001296 mTmpValue = null;
1297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05001299 if (tmpValue == null) {
1300 return new TypedValue();
1301 }
1302 return tmpValue;
1303 }
1304
1305 /**
1306 * Returns a TypedValue to the pool. After calling this method, the
1307 * specified TypedValue should no longer be accessed.
1308 *
1309 * @param value the typed value to return to the pool
1310 */
1311 private void releaseTempTypedValue(TypedValue value) {
1312 synchronized (mTmpValueLock) {
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001313 if (mTmpValue == null) {
1314 mTmpValue = value;
1315 }
1316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 }
1318
1319 /**
1320 * Open a data stream for reading a raw resource. This can only be used
Andy Stadlerf8a7cea2009-04-10 16:24:47 -07001321 * 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 -08001322 * used to open drawable, sound, and raw resources; it will fail on string
1323 * and color resources.
1324 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001325 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 * @param value The TypedValue object to hold the resource information.
1327 *
1328 * @return InputStream Access to the resource data.
1329 *
1330 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 */
Chris Craikceb26932018-02-01 15:51:34 -08001332 @NonNull
Tor Norbye7b9c9122013-05-30 16:48:33 -07001333 public InputStream openRawResource(@RawRes int id, TypedValue value)
1334 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001335 return mResourcesImpl.openRawResource(id, value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 }
1337
1338 /**
1339 * Open a file descriptor for reading a raw resource. This can only be used
1340 * with resources whose value is the name of an asset files -- that is, it can be
1341 * used to open drawable, sound, and raw resources; it will fail on string
1342 * and color resources.
1343 *
1344 * <p>This function only works for resources that are stored in the package
1345 * as uncompressed data, which typically includes things like mp3 files
1346 * and png images.
1347 *
Adam Lesinski50954d22017-04-14 18:41:52 -07001348 * @param id The resource identifier to open, as generated by the aapt tool.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 *
1350 * @return AssetFileDescriptor A new file descriptor you can use to read
1351 * the resource. This includes the file descriptor itself, as well as the
1352 * offset and length of data where the resource appears in the file. A
1353 * null is returned if the file exists but is compressed.
1354 *
1355 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1356 *
1357 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001358 public AssetFileDescriptor openRawResourceFd(@RawRes int id)
1359 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001360 final TypedValue value = obtainTempTypedValue();
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001361 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001362 return mResourcesImpl.openRawResourceFd(id, value);
Dianne Hackborn50707cc2013-02-08 15:32:05 -08001363 } finally {
Alan Viverette4d07bc92015-11-16 10:19:12 -05001364 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 }
1366 }
1367
1368 /**
1369 * Return the raw data associated with a particular resource ID.
1370 *
1371 * @param id The desired resource identifier, as generated by the aapt
1372 * tool. This integer encodes the package, type, and resource
1373 * entry. The value 0 is an invalid identifier.
1374 * @param outValue Object in which to place the resource data.
1375 * @param resolveRefs If true, a resource that is a reference to another
1376 * resource will be followed so that you receive the
1377 * actual final resource data. If false, the TypedValue
1378 * will be filled in with the reference itself.
1379 *
1380 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1381 *
1382 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001383 public void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001385 mResourcesImpl.getValue(id, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 }
1387
1388 /**
Kenny Root55fc8502010-10-28 14:47:01 -07001389 * Get the raw value associated with a resource with associated density.
1390 *
1391 * @param id resource identifier
1392 * @param density density in DPI
1393 * @param resolveRefs If true, a resource that is a reference to another
1394 * resource will be followed so that you receive the actual final
1395 * resource data. If false, the TypedValue will be filled in with
1396 * the reference itself.
1397 * @throws NotFoundException Throws NotFoundException if the given ID does
1398 * not exist.
1399 * @see #getValue(String, TypedValue, boolean)
Kenny Root55fc8502010-10-28 14:47:01 -07001400 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001401 public void getValueForDensity(@AnyRes int id, int density, TypedValue outValue,
1402 boolean resolveRefs) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001403 mResourcesImpl.getValueForDensity(id, density, outValue, resolveRefs);
Kenny Root55fc8502010-10-28 14:47:01 -07001404 }
1405
1406 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 * Return the raw data associated with a particular resource ID.
1408 * See getIdentifier() for information on how names are mapped to resource
1409 * IDs, and getString(int) for information on how string resources are
1410 * retrieved.
1411 *
1412 * <p>Note: use of this function is discouraged. It is much more
1413 * efficient to retrieve resources by identifier than by name.
1414 *
1415 * @param name The name of the desired resource. This is passed to
1416 * getIdentifier() with a default type of "string".
1417 * @param outValue Object in which to place the resource data.
1418 * @param resolveRefs If true, a resource that is a reference to another
1419 * resource will be followed so that you receive the
1420 * actual final resource data. If false, the TypedValue
1421 * will be filled in with the reference itself.
1422 *
1423 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1424 *
1425 */
1426 public void getValue(String name, TypedValue outValue, boolean resolveRefs)
1427 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001428 mResourcesImpl.getValue(name, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 }
1430
Aurimas Liutikasaae06632019-01-30 13:16:27 -08001431
1432 /**
Aurimas Liutikas29a90d62019-03-07 15:47:38 -08001433 * Returns the resource ID of the resource that was used to create this AttributeSet.
1434 *
Aurimas Liutikasaae06632019-01-30 13:16:27 -08001435 * @param set AttributeSet for which we want to find the source.
Aurimas Liutikas29a90d62019-03-07 15:47:38 -08001436 * @return The resource ID for the source that is backing the given AttributeSet or
1437 * {@link Resources#ID_NULL} if the AttributeSet is {@code null}.
Aurimas Liutikasaae06632019-01-30 13:16:27 -08001438 */
1439 @AnyRes
1440 public static int getAttributeSetSourceResId(@Nullable AttributeSet set) {
1441 return ResourcesImpl.getAttributeSetSourceResId(set);
1442 }
1443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 /**
1445 * This class holds the current attribute values for a particular theme.
1446 * In other words, a Theme is a set of values for resource attributes;
1447 * these are used in conjunction with {@link TypedArray}
1448 * to resolve the final value for an attribute.
1449 *
1450 * <p>The Theme's attributes come into play in two ways: (1) a styled
1451 * attribute can explicit reference a value in the theme through the
1452 * "?themeAttribute" syntax; (2) if no value has been defined for a
1453 * particular styled attribute, as a last resort we will try to find that
1454 * attribute's value in the Theme.
1455 *
1456 * <p>You will normally use the {@link #obtainStyledAttributes} APIs to
1457 * retrieve XML attributes with style and theme information applied.
1458 */
1459 public final class Theme {
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001460 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001461 private ResourcesImpl.ThemeImpl mThemeImpl;
1462
1463 private Theme() {
1464 }
1465
1466 void setImpl(ResourcesImpl.ThemeImpl impl) {
1467 mThemeImpl = impl;
1468 }
1469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 /**
1471 * Place new attribute values into the theme. The style resource
1472 * specified by <var>resid</var> will be retrieved from this Theme's
1473 * resources, its values placed into the Theme object.
1474 *
1475 * <p>The semantics of this function depends on the <var>force</var>
1476 * argument: If false, only values that are not already defined in
1477 * the theme will be copied from the system resource; otherwise, if
1478 * any of the style's attributes are already defined in the theme, the
1479 * current values in the theme will be overwritten.
1480 *
Alan Viverette75257ce2014-05-22 19:31:38 -07001481 * @param resId The resource ID of a style resource from which to
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 * obtain attribute values.
1483 * @param force If true, values in the style resource will always be
1484 * used in the theme; otherwise, they will only be used
1485 * if not already defined in the theme.
1486 */
Alan Viverette75257ce2014-05-22 19:31:38 -07001487 public void applyStyle(int resId, boolean force) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001488 mThemeImpl.applyStyle(resId, force);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 }
1490
1491 /**
1492 * Set this theme to hold the same contents as the theme
1493 * <var>other</var>. If both of these themes are from the same
1494 * Resources object, they will be identical after this function
1495 * returns. If they are from different Resources, only the resources
1496 * they have in common will be set in this theme.
1497 *
1498 * @param other The existing Theme to copy from.
1499 */
1500 public void setTo(Theme other) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001501 mThemeImpl.setTo(other.mThemeImpl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 }
1503
1504 /**
John Spurlock330dd532012-12-18 12:03:11 -05001505 * Return a TypedArray holding the values defined by
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 * <var>Theme</var> which are listed in <var>attrs</var>.
1507 *
Scott Main183bf112012-08-13 19:12:13 -07001508 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1509 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 *
Adam Lesinski5ec88752017-04-12 14:45:14 -07001511 * @param attrs The desired attributes. These attribute IDs must be sorted in ascending
1512 * order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 *
1514 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1515 *
1516 * @return Returns a TypedArray holding an array of the attribute values.
1517 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1518 * when done with it.
1519 *
1520 * @see Resources#obtainAttributes
1521 * @see #obtainStyledAttributes(int, int[])
1522 * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
1523 */
Aurimas Liutikas77acf4b2018-12-19 17:31:03 -08001524 @NonNull
1525 public TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001526 return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 }
1528
1529 /**
John Spurlock330dd532012-12-18 12:03:11 -05001530 * Return a TypedArray holding the values defined by the style
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 * resource <var>resid</var> which are listed in <var>attrs</var>.
1532 *
Scott Main183bf112012-08-13 19:12:13 -07001533 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1534 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 *
Alan Viverette395cd012015-08-11 17:27:04 -04001536 * @param resId The desired style resource.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001537 * @param attrs The desired attributes in the style. These attribute IDs must be sorted in
1538 * ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 *
1540 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
1541 *
1542 * @return Returns a TypedArray holding an array of the attribute values.
1543 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1544 * when done with it.
1545 *
1546 * @see Resources#obtainAttributes
1547 * @see #obtainStyledAttributes(int[])
1548 * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
1549 */
Aurimas Liutikas77acf4b2018-12-19 17:31:03 -08001550 @NonNull
1551 public TypedArray obtainStyledAttributes(@StyleRes int resId,
1552 @NonNull @StyleableRes int[] attrs)
Tor Norbyec91531a2015-04-01 17:41:55 -07001553 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001554 return mThemeImpl.obtainStyledAttributes(this, null, attrs, 0, resId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 }
1556
1557 /**
John Spurlock330dd532012-12-18 12:03:11 -05001558 * Return a TypedArray holding the attribute values in
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 * <var>set</var>
1560 * that are listed in <var>attrs</var>. In addition, if the given
1561 * AttributeSet specifies a style class (through the "style" attribute),
1562 * that style will be applied on top of the base attributes it defines.
1563 *
Scott Main183bf112012-08-13 19:12:13 -07001564 * <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
1565 * with the array.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 *
1567 * <p>When determining the final value of a particular attribute, there
1568 * are four inputs that come into play:</p>
1569 *
1570 * <ol>
1571 * <li> Any attribute values in the given AttributeSet.
1572 * <li> The style resource specified in the AttributeSet (named
1573 * "style").
1574 * <li> The default style specified by <var>defStyleAttr</var> and
1575 * <var>defStyleRes</var>
1576 * <li> The base values in this theme.
1577 * </ol>
1578 *
1579 * <p>Each of these inputs is considered in-order, with the first listed
1580 * taking precedence over the following ones. In other words, if in the
1581 * AttributeSet you have supplied <code>&lt;Button
1582 * textColor="#ff000000"&gt;</code>, then the button's text will
1583 * <em>always</em> be black, regardless of what is specified in any of
1584 * the styles.
1585 *
1586 * @param set The base set of attribute values. May be null.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001587 * @param attrs The desired attributes to be retrieved. These attribute IDs must be sorted
1588 * in ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 * @param defStyleAttr An attribute in the current theme that contains a
1590 * reference to a style resource that supplies
John Spurlock330dd532012-12-18 12:03:11 -05001591 * defaults values for the TypedArray. Can be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 * 0 to not look for defaults.
1593 * @param defStyleRes A resource identifier of a style resource that
John Spurlock330dd532012-12-18 12:03:11 -05001594 * supplies default values for the TypedArray,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 * used only if defStyleAttr is 0 or can not be found
1596 * in the theme. Can be 0 to not look for defaults.
1597 *
1598 * @return Returns a TypedArray holding an array of the attribute values.
1599 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1600 * when done with it.
1601 *
1602 * @see Resources#obtainAttributes
1603 * @see #obtainStyledAttributes(int[])
1604 * @see #obtainStyledAttributes(int, int[])
1605 */
Aurimas Liutikas77acf4b2018-12-19 17:31:03 -08001606 @NonNull
1607 public TypedArray obtainStyledAttributes(@Nullable AttributeSet set,
1608 @NonNull @StyleableRes int[] attrs, @AttrRes int defStyleAttr,
1609 @StyleRes int defStyleRes) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001610 return mThemeImpl.obtainStyledAttributes(this, set, attrs, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 }
1612
1613 /**
Alan Viverette52b999f2014-03-24 18:00:26 -07001614 * Retrieve the values for a set of attributes in the Theme. The
1615 * contents of the typed array are ultimately filled in by
1616 * {@link Resources#getValue}.
1617 *
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001618 * @param values The base set of attribute values, must be equal in
1619 * length to {@code attrs}. All values must be of type
1620 * {@link TypedValue#TYPE_ATTRIBUTE}.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001621 * @param attrs The desired attributes to be retrieved. These attribute IDs must be sorted
1622 * in ascending order.
Alan Viverette52b999f2014-03-24 18:00:26 -07001623 * @return Returns a TypedArray holding an array of the attribute
1624 * values. Be sure to call {@link TypedArray#recycle()}
1625 * when done with it.
1626 * @hide
1627 */
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001628 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001629 @UnsupportedAppUsage
Alan Viverette7f4a63d2014-10-30 10:29:03 -07001630 public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001631 return mThemeImpl.resolveAttributes(this, values, attrs);
Alan Viverette52b999f2014-03-24 18:00:26 -07001632 }
1633
1634 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 * Retrieve the value of an attribute in the Theme. The contents of
1636 * <var>outValue</var> are ultimately filled in by
1637 * {@link Resources#getValue}.
1638 *
1639 * @param resid The resource identifier of the desired theme
1640 * attribute.
1641 * @param outValue Filled in with the ultimate resource value supplied
1642 * by the attribute.
1643 * @param resolveRefs If true, resource references will be walked; if
1644 * false, <var>outValue</var> may be a
1645 * TYPE_REFERENCE. In either case, it will never
1646 * be a TYPE_ATTRIBUTE.
1647 *
1648 * @return boolean Returns true if the attribute was found and
1649 * <var>outValue</var> is valid, else false.
1650 */
Alan Viverette52b999f2014-03-24 18:00:26 -07001651 public boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001652 return mThemeImpl.resolveAttribute(resid, outValue, resolveRefs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 }
1654
1655 /**
Jon Miranda042ad632014-09-03 17:57:35 -07001656 * Gets all of the attribute ids associated with this {@link Theme}. For debugging only.
1657 *
1658 * @return The int array containing attribute ids associated with this {@link Theme}.
1659 * @hide
1660 */
1661 public int[] getAllAttributes() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001662 return mThemeImpl.getAllAttributes();
Jon Miranda042ad632014-09-03 17:57:35 -07001663 }
1664
1665 /**
Alan Viverette52b999f2014-03-24 18:00:26 -07001666 * Returns the resources to which this theme belongs.
1667 *
1668 * @return Resources to which this theme belongs.
1669 */
1670 public Resources getResources() {
1671 return Resources.this;
1672 }
1673
1674 /**
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001675 * Return a drawable object associated with a particular resource ID
1676 * and styled for the Theme.
1677 *
1678 * @param id The desired resource identifier, as generated by the aapt
1679 * tool. This integer encodes the package, type, and resource
1680 * entry. The value 0 is an invalid identifier.
1681 * @return Drawable An object that can be used to draw this resource.
1682 * @throws NotFoundException Throws NotFoundException if the given ID
1683 * does not exist.
1684 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001685 public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001686 return Resources.this.getDrawable(id, this);
1687 }
1688
1689 /**
Alan Viverettec1d52792015-05-05 09:49:03 -07001690 * Returns a bit mask of configuration changes that will impact this
1691 * theme (and thus require completely reloading it).
1692 *
1693 * @return a bit mask of configuration changes, as defined by
1694 * {@link ActivityInfo}
1695 * @see ActivityInfo
1696 */
Alan Viverette9ad386b2017-01-26 14:00:20 -05001697 public @Config int getChangingConfigurations() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001698 return mThemeImpl.getChangingConfigurations();
Alan Viverettec1d52792015-05-05 09:49:03 -07001699 }
1700
1701 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 * Print contents of this theme out to the log. For debugging only.
1703 *
1704 * @param priority The log priority to use.
1705 * @param tag The log tag to use.
1706 * @param prefix Text to prefix each line printed.
1707 */
1708 public void dump(int priority, String tag, String prefix) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001709 mThemeImpl.dump(priority, tag, prefix);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 }
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001711
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001712 // Needed by layoutlib.
1713 /*package*/ long getNativeTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001714 return mThemeImpl.getNativeTheme();
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001715 }
1716
1717 /*package*/ int getAppliedStyleResId() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001718 return mThemeImpl.getAppliedStyleResId();
Deepanshu Guptabfec73c2014-03-11 18:02:44 -07001719 }
Alan Viverette75257ce2014-05-22 19:31:38 -07001720
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001721 /**
1722 * @hide
1723 */
1724 public ThemeKey getKey() {
1725 return mThemeImpl.getKey();
Alan Viverette75257ce2014-05-22 19:31:38 -07001726 }
Jon Miranda836c0a82014-08-11 12:32:26 -07001727
1728 private String getResourceNameFromHexString(String hexString) {
1729 return getResourceName(Integer.parseInt(hexString, 16));
1730 }
1731
1732 /**
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001733 * Parses {@link #getKey()} and returns a String array that holds pairs of
Alan Viverettee54d2452015-05-06 10:41:43 -07001734 * adjacent Theme data: resource name followed by whether or not it was
1735 * forced, as specified by {@link #applyStyle(int, boolean)}.
Jon Miranda836c0a82014-08-11 12:32:26 -07001736 *
1737 * @hide
1738 */
1739 @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
1740 public String[] getTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001741 return mThemeImpl.getTheme();
Jon Miranda836c0a82014-08-11 12:32:26 -07001742 }
Alan Viverettee54d2452015-05-06 10:41:43 -07001743
Siva Velusamy0d857b92015-04-22 10:23:56 -07001744 /** @hide */
1745 public void encode(@NonNull ViewHierarchyEncoder encoder) {
1746 encoder.beginObject(this);
Alan Viveretteac674092015-05-08 11:04:47 -07001747 final String[] properties = getTheme();
Siva Velusamy0d857b92015-04-22 10:23:56 -07001748 for (int i = 0; i < properties.length; i += 2) {
1749 encoder.addProperty(properties[i], properties[i+1]);
1750 }
1751 encoder.endObject();
1752 }
1753
Alan Viverettee54d2452015-05-06 10:41:43 -07001754 /**
1755 * Rebases the theme against the parent Resource object's current
1756 * configuration by re-applying the styles passed to
1757 * {@link #applyStyle(int, boolean)}.
Alan Viverettee54d2452015-05-06 10:41:43 -07001758 */
1759 public void rebase() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001760 mThemeImpl.rebase();
Alan Viverettee54d2452015-05-06 10:41:43 -07001761 }
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001762
1763 /**
1764 * Returns the resource ID for the style specified using {@code style="..."} in the
1765 * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise if not
1766 * specified or otherwise not applicable.
1767 * <p>
1768 * Each {@link android.view.View} can have an explicit style specified in the layout file.
1769 * This style is used first during the {@link android.view.View} attribute resolution, then
1770 * if an attribute is not defined there the resource system looks at default style and theme
1771 * as fallbacks.
1772 *
1773 * @param set The base set of attribute values.
1774 *
1775 * @return The resource ID for the style specified using {@code style="..."} in the
1776 * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise
1777 * if not specified or otherwise not applicable.
1778 */
1779 @StyleRes
1780 public int getExplicitStyle(@Nullable AttributeSet set) {
1781 if (set == null) {
1782 return ID_NULL;
1783 }
1784 int styleAttr = set.getStyleAttribute();
1785 if (styleAttr == ID_NULL) {
1786 return ID_NULL;
1787 }
1788 String styleAttrType = getResources().getResourceTypeName(styleAttr);
1789 if ("attr".equals(styleAttrType)) {
1790 TypedValue explicitStyle = new TypedValue();
1791 boolean resolved = resolveAttribute(styleAttr, explicitStyle, true);
1792 if (resolved) {
1793 return explicitStyle.resourceId;
1794 }
1795 } else if ("style".equals(styleAttrType)) {
1796 return styleAttr;
1797 }
1798 return ID_NULL;
1799 }
1800
1801 /**
1802 * Returns the ordered list of resource ID that are considered when resolving attribute
1803 * values when making an equivalent call to
1804 * {@link #obtainStyledAttributes(AttributeSet, int[], int, int)} . The list will include
1805 * a set of explicit styles ({@code explicitStyleRes} and it will include the default styles
1806 * ({@code defStyleAttr} and {@code defStyleRes}).
1807 *
1808 * @param defStyleAttr An attribute in the current theme that contains a
1809 * reference to a style resource that supplies
1810 * defaults values for the TypedArray. Can be
1811 * 0 to not look for defaults.
1812 * @param defStyleRes A resource identifier of a style resource that
1813 * supplies default values for the TypedArray,
1814 * used only if defStyleAttr is 0 or can not be found
1815 * in the theme. Can be 0 to not look for defaults.
1816 * @param explicitStyleRes A resource identifier of an explicit style resource.
1817 * @return ordered list of resource ID that are considered when resolving attribute values.
1818 */
Aurimas Liutikas6c15bc02019-02-28 11:16:06 -08001819 @NonNull
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001820 public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr,
1821 @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) {
Aurimas Liutikas6c15bc02019-02-28 11:16:06 -08001822 int[] stack = mThemeImpl.getAttributeResolutionStack(
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001823 defStyleAttr, defStyleRes, explicitStyleRes);
Aurimas Liutikas6c15bc02019-02-28 11:16:06 -08001824 if (stack == null) {
1825 return new int[0];
1826 } else {
1827 return stack;
1828 }
Aurimas Liutikas8f004c82019-01-17 17:20:10 -08001829 }
Alan Viverettee54d2452015-05-06 10:41:43 -07001830 }
1831
1832 static class ThemeKey implements Cloneable {
1833 int[] mResId;
1834 boolean[] mForce;
1835 int mCount;
1836
1837 private int mHashCode = 0;
1838
1839 public void append(int resId, boolean force) {
1840 if (mResId == null) {
1841 mResId = new int[4];
1842 }
1843
1844 if (mForce == null) {
1845 mForce = new boolean[4];
1846 }
1847
1848 mResId = GrowingArrayUtils.append(mResId, mCount, resId);
1849 mForce = GrowingArrayUtils.append(mForce, mCount, force);
1850 mCount++;
1851
1852 mHashCode = 31 * (31 * mHashCode + resId) + (force ? 1 : 0);
1853 }
1854
1855 /**
1856 * Sets up this key as a deep copy of another key.
1857 *
1858 * @param other the key to deep copy into this key
1859 */
1860 public void setTo(ThemeKey other) {
1861 mResId = other.mResId == null ? null : other.mResId.clone();
1862 mForce = other.mForce == null ? null : other.mForce.clone();
1863 mCount = other.mCount;
Hiroshi Sumita4a3beba2019-02-25 18:52:24 +09001864 mHashCode = other.mHashCode;
Alan Viverettee54d2452015-05-06 10:41:43 -07001865 }
1866
1867 @Override
1868 public int hashCode() {
1869 return mHashCode;
1870 }
1871
1872 @Override
1873 public boolean equals(Object o) {
1874 if (this == o) {
1875 return true;
1876 }
1877
1878 if (o == null || getClass() != o.getClass() || hashCode() != o.hashCode()) {
1879 return false;
1880 }
1881
1882 final ThemeKey t = (ThemeKey) o;
1883 if (mCount != t.mCount) {
1884 return false;
1885 }
1886
1887 final int N = mCount;
1888 for (int i = 0; i < N; i++) {
1889 if (mResId[i] != t.mResId[i] || mForce[i] != t.mForce[i]) {
1890 return false;
1891 }
1892 }
1893
1894 return true;
1895 }
1896
1897 /**
1898 * @return a shallow copy of this key
1899 */
1900 @Override
1901 public ThemeKey clone() {
1902 final ThemeKey other = new ThemeKey();
1903 other.mResId = mResId;
1904 other.mForce = mForce;
1905 other.mCount = mCount;
John Reck4feb3262015-07-13 14:42:43 -07001906 other.mHashCode = mHashCode;
Alan Viverettee54d2452015-05-06 10:41:43 -07001907 return other;
1908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 }
1910
1911 /**
1912 * Generate a new Theme object for this set of Resources. It initially
1913 * starts out empty.
Jon Miranda836c0a82014-08-11 12:32:26 -07001914 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 * @return Theme The newly created Theme container.
1916 */
1917 public final Theme newTheme() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001918 Theme theme = new Theme();
1919 theme.setImpl(mResourcesImpl.newThemeImpl());
Adam Lesinski4fed9712017-05-23 13:14:54 -07001920 synchronized (mThemeRefs) {
1921 mThemeRefs.add(new WeakReference<>(theme));
Richard Uhlerdd6a0db2018-04-26 15:09:30 +01001922
1923 // Clean up references to garbage collected themes
1924 if (mThemeRefs.size() > mThemeRefsNextFlushSize) {
1925 mThemeRefs.removeIf(ref -> ref.get() == null);
1926 mThemeRefsNextFlushSize = Math.max(MIN_THEME_REFS_FLUSH_SIZE,
1927 2 * mThemeRefs.size());
1928 }
Adam Lesinski4fed9712017-05-23 13:14:54 -07001929 }
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001930 return theme;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001931 }
1932
1933 /**
1934 * Retrieve a set of basic attribute values from an AttributeSet, not
1935 * performing styling of them using a theme and/or style resources.
Jon Miranda836c0a82014-08-11 12:32:26 -07001936 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001937 * @param set The current attribute values to retrieve.
Adam Lesinski5ec88752017-04-12 14:45:14 -07001938 * @param attrs The specific attributes to be retrieved. These attribute IDs must be sorted in
1939 * ascending order.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001940 * @return Returns a TypedArray holding an array of the attribute values.
1941 * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
1942 * when done with it.
1943 *
1944 * @see Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
1945 */
Adam Lesinski5ec88752017-04-12 14:45:14 -07001946 public TypedArray obtainAttributes(AttributeSet set, @StyleableRes int[] attrs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001947 int len = attrs.length;
Alan Viverette52b999f2014-03-24 18:00:26 -07001948 TypedArray array = TypedArray.obtain(this, len);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949
1950 // XXX note that for now we only work with compiled XML files.
1951 // To support generic XML files we will need to manually parse
1952 // out the attributes from the XML file (applying type information
1953 // contained in the resources and such).
1954 XmlBlock.Parser parser = (XmlBlock.Parser)set;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001955 mResourcesImpl.getAssets().retrieveAttributes(parser, attrs, array.mData, array.mIndices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 array.mXml = parser;
1958
1959 return array;
1960 }
Mitsuru Oshimae5fb3282009-06-09 21:16:08 -07001961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 /**
1963 * Store the newly updated configuration.
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -07001964 *
1965 * @deprecated See {@link android.content.Context#createConfigurationContext(Configuration)}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 */
Adam Lesinskiaa19d5e2016-07-15 17:49:49 -07001967 @Deprecated
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001968 public void updateConfiguration(Configuration config, DisplayMetrics metrics) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001969 updateConfiguration(config, metrics, null);
1970 }
1971
1972 /**
1973 * @hide
1974 */
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001975 public void updateConfiguration(Configuration config, DisplayMetrics metrics,
1976 CompatibilityInfo compat) {
1977 mResourcesImpl.updateConfiguration(config, metrics, compat);
Narayan Kamath21fc8ba2014-03-05 18:42:23 +00001978 }
1979
1980 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 * Update the system resources configuration if they have previously
1982 * been initialized.
1983 *
1984 * @hide
1985 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001986 @UnsupportedAppUsage
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001987 public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics,
1988 CompatibilityInfo compat) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 if (mSystem != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001990 mSystem.updateConfiguration(config, metrics, compat);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001991 //Log.i(TAG, "Updated system resources " + mSystem
1992 // + ": " + mSystem.getConfiguration());
1993 }
1994 }
1995
1996 /**
1997 * Return the current display metrics that are in effect for this resource
1998 * object. The returned object should be treated as read-only.
1999 *
2000 * @return The resource's current display metrics.
2001 */
2002 public DisplayMetrics getDisplayMetrics() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002003 return mResourcesImpl.getDisplayMetrics();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 }
2005
Adam Lesinski4ece3d62016-06-16 18:05:41 -07002006 /** @hide */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002007 @UnsupportedAppUsage
Adam Lesinski4ece3d62016-06-16 18:05:41 -07002008 public DisplayAdjustments getDisplayAdjustments() {
2009 return mResourcesImpl.getDisplayAdjustments();
2010 }
2011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012 /**
2013 * Return the current configuration that is in effect for this resource
2014 * object. The returned object should be treated as read-only.
2015 *
2016 * @return The resource's current configuration.
2017 */
2018 public Configuration getConfiguration() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002019 return mResourcesImpl.getConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 }
Filip Gruszczynski23493322015-07-29 17:02:59 -07002021
2022 /** @hide */
2023 public Configuration[] getSizeConfigurations() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002024 return mResourcesImpl.getSizeConfigurations();
2025 }
Filip Gruszczynski23493322015-07-29 17:02:59 -07002026
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002027 /**
2028 * Return the compatibility mode information for the application.
2029 * The returned object should be treated as read-only.
2030 *
Dianne Hackborn3904d032011-05-27 12:09:11 -07002031 * @return compatibility info.
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002032 * @hide
2033 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002034 @UnsupportedAppUsage
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002035 public CompatibilityInfo getCompatibilityInfo() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002036 return mResourcesImpl.getCompatibilityInfo();
Mitsuru Oshima9189cab2009-06-03 11:19:12 -07002037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038
2039 /**
Dianne Hackborna53b8282009-07-17 11:13:48 -07002040 * This is just for testing.
2041 * @hide
2042 */
Adam Lesinski082614c2016-03-04 14:33:47 -08002043 @VisibleForTesting
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002044 @UnsupportedAppUsage
Dianne Hackborna53b8282009-07-17 11:13:48 -07002045 public void setCompatibilityInfo(CompatibilityInfo ci) {
Adam Lesinski79a8ffe2013-09-19 20:33:15 -07002046 if (ci != null) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002047 mResourcesImpl.updateConfiguration(null, null, ci);
Adam Lesinski79a8ffe2013-09-19 20:33:15 -07002048 }
Dianne Hackborna53b8282009-07-17 11:13:48 -07002049 }
2050
2051 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052 * Return a resource identifier for the given resource name. A fully
2053 * qualified resource name is of the form "package:type/entry". The first
2054 * two components (package and type) are optional if defType and
2055 * defPackage, respectively, are specified here.
2056 *
2057 * <p>Note: use of this function is discouraged. It is much more
2058 * efficient to retrieve resources by identifier than by name.
2059 *
2060 * @param name The name of the desired resource.
2061 * @param defType Optional default resource type to find, if "type/" is
2062 * not included in the name. Can be null to require an
2063 * explicit type.
2064 * @param defPackage Optional default package to find, if "package:" is
2065 * not included in the name. Can be null to require an
2066 * explicit package.
2067 *
2068 * @return int The associated resource identifier. Returns 0 if no such
2069 * resource was found. (0 is not a valid resource ID.)
2070 */
2071 public int getIdentifier(String name, String defType, String defPackage) {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002072 return mResourcesImpl.getIdentifier(name, defType, defPackage);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002073 }
2074
2075 /**
Jeff Sharkey47b50332013-03-15 14:46:46 -07002076 * Return true if given resource identifier includes a package.
2077 *
2078 * @hide
2079 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002080 public static boolean resourceHasPackage(@AnyRes int resid) {
Jeff Sharkey47b50332013-03-15 14:46:46 -07002081 return (resid >>> 24) != 0;
2082 }
2083
2084 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002085 * Return the full name for a given resource identifier. This name is
2086 * a single string of the form "package:type/entry".
2087 *
2088 * @param resid The resource identifier whose name is to be retrieved.
2089 *
2090 * @return A string holding the name of the resource.
2091 *
2092 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
2093 *
2094 * @see #getResourcePackageName
2095 * @see #getResourceTypeName
2096 * @see #getResourceEntryName
2097 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002098 public String getResourceName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002099 return mResourcesImpl.getResourceName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100 }
2101
2102 /**
2103 * Return the package name for a given resource identifier.
2104 *
2105 * @param resid The resource identifier whose package name is to be
2106 * retrieved.
2107 *
2108 * @return A string holding the package name of the resource.
2109 *
2110 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
2111 *
2112 * @see #getResourceName
2113 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002114 public String getResourcePackageName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002115 return mResourcesImpl.getResourcePackageName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 }
2117
2118 /**
2119 * Return the type name for a given resource identifier.
2120 *
2121 * @param resid The resource identifier whose type name is to be
2122 * retrieved.
2123 *
2124 * @return A string holding the type name of the resource.
2125 *
2126 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
2127 *
2128 * @see #getResourceName
2129 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002130 public String getResourceTypeName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002131 return mResourcesImpl.getResourceTypeName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 }
Winson2f3669b2019-01-11 11:28:34 -08002133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002134 /**
2135 * Return the entry name for a given resource identifier.
Winson2f3669b2019-01-11 11:28:34 -08002136 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 * @param resid The resource identifier whose entry name is to be
2138 * retrieved.
Winson2f3669b2019-01-11 11:28:34 -08002139 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 * @return A string holding the entry name of the resource.
Winson2f3669b2019-01-11 11:28:34 -08002141 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
Winson2f3669b2019-01-11 11:28:34 -08002143 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 * @see #getResourceName
2145 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07002146 public String getResourceEntryName(@AnyRes int resid) throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002147 return mResourcesImpl.getResourceEntryName(resid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 }
Winson2f3669b2019-01-11 11:28:34 -08002149
2150 /**
2151 * Return formatted log of the last retrieved resource's resolution path.
2152 *
2153 * @return A string holding a formatted log of the steps taken to resolve the last resource.
2154 *
2155 * @throws NotFoundException Throws NotFoundException if there hasn't been a resource
2156 * resolved yet.
2157 *
2158 * @hide
2159 */
2160 public String getLastResourceResolution() throws NotFoundException {
2161 return mResourcesImpl.getLastResourceResolution();
2162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163
2164 /**
2165 * Parse a series of {@link android.R.styleable#Extra &lt;extra&gt;} tags from
2166 * an XML file. You call this when you are at the parent tag of the
Dianne Hackborndef15372010-08-15 12:43:52 -07002167 * 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 -08002168 * This will call {@link #parseBundleExtra} for each extra tag encountered.
2169 *
2170 * @param parser The parser from which to retrieve the extras.
2171 * @param outBundle A Bundle in which to place all parsed extras.
2172 * @throws XmlPullParserException
2173 * @throws IOException
2174 */
2175 public void parseBundleExtras(XmlResourceParser parser, Bundle outBundle)
2176 throws XmlPullParserException, IOException {
2177 int outerDepth = parser.getDepth();
2178 int type;
2179 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2180 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2181 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2182 continue;
2183 }
2184
2185 String nodeName = parser.getName();
2186 if (nodeName.equals("extra")) {
2187 parseBundleExtra("extra", parser, outBundle);
2188 XmlUtils.skipCurrentTag(parser);
2189
2190 } else {
2191 XmlUtils.skipCurrentTag(parser);
2192 }
2193 }
2194 }
2195
2196 /**
2197 * Parse a name/value pair out of an XML tag holding that data. The
2198 * AttributeSet must be holding the data defined by
2199 * {@link android.R.styleable#Extra}. The following value types are supported:
2200 * <ul>
2201 * <li> {@link TypedValue#TYPE_STRING}:
2202 * {@link Bundle#putCharSequence Bundle.putCharSequence()}
2203 * <li> {@link TypedValue#TYPE_INT_BOOLEAN}:
2204 * {@link Bundle#putCharSequence Bundle.putBoolean()}
2205 * <li> {@link TypedValue#TYPE_FIRST_INT}-{@link TypedValue#TYPE_LAST_INT}:
2206 * {@link Bundle#putCharSequence Bundle.putBoolean()}
2207 * <li> {@link TypedValue#TYPE_FLOAT}:
2208 * {@link Bundle#putCharSequence Bundle.putFloat()}
2209 * </ul>
2210 *
2211 * @param tagName The name of the tag these attributes come from; this is
2212 * only used for reporting error messages.
2213 * @param attrs The attributes from which to retrieve the name/value pair.
2214 * @param outBundle The Bundle in which to place the parsed value.
2215 * @throws XmlPullParserException If the attributes are not valid.
2216 */
2217 public void parseBundleExtra(String tagName, AttributeSet attrs,
2218 Bundle outBundle) throws XmlPullParserException {
2219 TypedArray sa = obtainAttributes(attrs,
2220 com.android.internal.R.styleable.Extra);
2221
2222 String name = sa.getString(
2223 com.android.internal.R.styleable.Extra_name);
2224 if (name == null) {
2225 sa.recycle();
2226 throw new XmlPullParserException("<" + tagName
2227 + "> requires an android:name attribute at "
2228 + attrs.getPositionDescription());
2229 }
2230
2231 TypedValue v = sa.peekValue(
2232 com.android.internal.R.styleable.Extra_value);
2233 if (v != null) {
2234 if (v.type == TypedValue.TYPE_STRING) {
2235 CharSequence cs = v.coerceToString();
2236 outBundle.putCharSequence(name, cs);
2237 } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
2238 outBundle.putBoolean(name, v.data != 0);
2239 } else if (v.type >= TypedValue.TYPE_FIRST_INT
2240 && v.type <= TypedValue.TYPE_LAST_INT) {
2241 outBundle.putInt(name, v.data);
2242 } else if (v.type == TypedValue.TYPE_FLOAT) {
2243 outBundle.putFloat(name, v.getFloat());
2244 } else {
2245 sa.recycle();
2246 throw new XmlPullParserException("<" + tagName
2247 + "> only supports string, integer, float, color, and boolean at "
2248 + attrs.getPositionDescription());
2249 }
2250 } else {
2251 sa.recycle();
2252 throw new XmlPullParserException("<" + tagName
2253 + "> requires an android:value or android:resource attribute at "
2254 + attrs.getPositionDescription());
2255 }
2256
2257 sa.recycle();
2258 }
2259
2260 /**
2261 * Retrieve underlying AssetManager storage for these resources.
2262 */
2263 public final AssetManager getAssets() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002264 return mResourcesImpl.getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265 }
2266
2267 /**
2268 * Call this to remove all cached loaded layout resources from the
2269 * Resources object. Only intended for use with performance testing
2270 * tools.
2271 */
2272 public final void flushLayoutCache() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002273 mResourcesImpl.flushLayoutCache();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 }
2275
2276 /**
2277 * Start preloading of resource data using this Resources object. Only
2278 * for use by the zygote process for loading common system resources.
2279 * {@hide}
2280 */
2281 public final void startPreloading() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002282 mResourcesImpl.startPreloading();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 }
2284
2285 /**
2286 * Called by zygote when it is done preloading resources, to change back
2287 * to normal Resources operation.
2288 */
2289 public final void finishPreloading() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002290 mResourcesImpl.finishPreloading();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07002292
Romain Guy3b748a42013-04-17 18:54:38 -07002293 /**
2294 * @hide
2295 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002296 @UnsupportedAppUsage
Alan Viverette52b999f2014-03-24 18:00:26 -07002297 public LongSparseArray<ConstantState> getPreloadedDrawables() {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002298 return mResourcesImpl.getPreloadedDrawables();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 }
2300
Alan Viverette10979612016-01-06 15:27:35 -05002301 /**
2302 * Loads an XML parser for the specified file.
2303 *
2304 * @param id the resource identifier for the file
2305 * @param type the type of resource (used for logging)
2306 * @return a parser for the specified XML file
2307 * @throws NotFoundException if the file could not be loaded
2308 */
2309 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002310 @UnsupportedAppUsage
Alan Viverette10979612016-01-06 15:27:35 -05002311 XmlResourceParser loadXmlResourceParser(@AnyRes int id, @NonNull String type)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 throws NotFoundException {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002313 final TypedValue value = obtainTempTypedValue();
Alan Viverette4d07bc92015-11-16 10:19:12 -05002314 try {
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002315 final ResourcesImpl impl = mResourcesImpl;
2316 impl.getValue(id, value, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 if (value.type == TypedValue.TYPE_STRING) {
Winson9947f1e2019-08-16 10:20:39 -07002318 return loadXmlResourceParser(value.string.toString(), id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 value.assetCookie, type);
2320 }
Alan Viverette4d07bc92015-11-16 10:19:12 -05002321 throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
2322 + " type #0x" + Integer.toHexString(value.type) + " is not valid");
2323 } finally {
2324 releaseTempTypedValue(value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 }
2326 }
Alan Viverette10979612016-01-06 15:27:35 -05002327
2328 /**
2329 * Loads an XML parser for the specified file.
2330 *
2331 * @param file the path for the XML file to parse
2332 * @param id the resource identifier for the file
2333 * @param assetCookie the asset cookie for the file
2334 * @param type the type of resource (used for logging)
2335 * @return a parser for the specified XML file
2336 * @throws NotFoundException if the file could not be loaded
2337 */
2338 @NonNull
Mathew Inwood5c0d3542018-08-14 13:54:31 +01002339 @UnsupportedAppUsage
Adam Lesinskifb302cc2016-02-29 16:50:38 -08002340 XmlResourceParser loadXmlResourceParser(String file, int id, int assetCookie,
2341 String type) throws NotFoundException {
2342 return mResourcesImpl.loadXmlResourceParser(file, id, assetCookie, type);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 }
2344
Alan Viverette45c4bbb2015-01-05 14:59:19 -08002345 /**
Adam Lesinski082614c2016-03-04 14:33:47 -08002346 * Called by ConfigurationBoundResourceCacheTest.
2347 * @hide
2348 */
2349 @VisibleForTesting
2350 public int calcConfigChanges(Configuration config) {
2351 return mResourcesImpl.calcConfigChanges(config);
2352 }
2353
2354 /**
Alan Viverette45c4bbb2015-01-05 14:59:19 -08002355 * Obtains styled attributes from the theme, if available, or unstyled
2356 * resources if the theme is null.
2357 *
2358 * @hide
2359 */
2360 public static TypedArray obtainAttributes(
2361 Resources res, Theme theme, AttributeSet set, int[] attrs) {
2362 if (theme == null) {
2363 return res.obtainAttributes(set, attrs);
2364 }
2365 return theme.obtainStyledAttributes(set, attrs, 0, 0);
2366 }
Winson9947f1e2019-08-16 10:20:39 -07002367
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002368 private void checkCallbacksRegistered() {
2369 if (mCallbacks == null) {
2370 throw new IllegalArgumentException("Cannot modify resource loaders of Resources"
2371 + " instances created outside of ResourcesManager");
Winson9947f1e2019-08-16 10:20:39 -07002372 }
Winson9947f1e2019-08-16 10:20:39 -07002373 }
2374
2375 /**
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002376 * Retrieves the list of loaders.
2377 *
2378 * <p>Loaders are listed in increasing precedence order. A loader will override the resources
2379 * and assets of loaders listed before itself.
Ryan Mitchelle2723072020-02-11 15:51:29 -08002380 * @hide
Winson9947f1e2019-08-16 10:20:39 -07002381 */
2382 @NonNull
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002383 public List<ResourcesLoader> getLoaders() {
2384 return mResourcesImpl.getAssets().getLoaders();
Winson9947f1e2019-08-16 10:20:39 -07002385 }
2386
2387 /**
Ryan Mitchelle2723072020-02-11 15:51:29 -08002388 * Adds a loader to the list of loaders. If the loader is already present in the list, the list
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002389 * will not be modified.
Winson9947f1e2019-08-16 10:20:39 -07002390 *
Ryan Mitchelle2723072020-02-11 15:51:29 -08002391 * @param loaders the loaders to add
Winson9947f1e2019-08-16 10:20:39 -07002392 */
Ryan Mitchelle2723072020-02-11 15:51:29 -08002393 public void addLoaders(@NonNull ResourcesLoader... loaders) {
2394 synchronized (mUpdateLock) {
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002395 checkCallbacksRegistered();
Ryan Mitchelle2723072020-02-11 15:51:29 -08002396 final List<ResourcesLoader> newLoaders =
2397 new ArrayList<>(mResourcesImpl.getAssets().getLoaders());
2398 final ArraySet<ResourcesLoader> loaderSet = new ArraySet<>(newLoaders);
Winson9947f1e2019-08-16 10:20:39 -07002399
Ryan Mitchelle2723072020-02-11 15:51:29 -08002400 for (int i = 0; i < loaders.length; i++) {
2401 final ResourcesLoader loader = loaders[i];
2402 if (!loaderSet.contains(loader)) {
2403 newLoaders.add(loader);
2404 }
2405 }
2406
2407 if (loaderSet.size() == newLoaders.size()) {
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002408 return;
Winson9947f1e2019-08-16 10:20:39 -07002409 }
2410
Ryan Mitchelle2723072020-02-11 15:51:29 -08002411 mCallbacks.onLoadersChanged(this, newLoaders);
2412 for (int i = loaderSet.size(), n = newLoaders.size(); i < n; i++) {
2413 newLoaders.get(i).registerOnProvidersChangedCallback(this, mCallbacks);
2414 }
Winson9947f1e2019-08-16 10:20:39 -07002415 }
2416 }
2417
2418 /**
Ryan Mitchelle2723072020-02-11 15:51:29 -08002419 * Removes loaders from the list of loaders. If the loader is not present in the list, the list
2420 * will not be modified.
Winson9947f1e2019-08-16 10:20:39 -07002421 *
Ryan Mitchelle2723072020-02-11 15:51:29 -08002422 * @param loaders the loaders to remove
Winson9947f1e2019-08-16 10:20:39 -07002423 */
Ryan Mitchelle2723072020-02-11 15:51:29 -08002424 public void removeLoaders(@NonNull ResourcesLoader... loaders) {
2425 synchronized (mUpdateLock) {
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002426 checkCallbacksRegistered();
Ryan Mitchelle2723072020-02-11 15:51:29 -08002427 final ArraySet<ResourcesLoader> removedLoaders = new ArraySet<>(loaders);
2428 final List<ResourcesLoader> newLoaders = new ArrayList<>();
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002429 final List<ResourcesLoader> oldLoaders = mResourcesImpl.getAssets().getLoaders();
Winson9947f1e2019-08-16 10:20:39 -07002430
Ryan Mitchelle2723072020-02-11 15:51:29 -08002431 for (int i = 0, n = oldLoaders.size(); i < n; i++) {
2432 final ResourcesLoader loader = oldLoaders.get(i);
2433 if (!removedLoaders.contains(loader)) {
2434 newLoaders.add(loader);
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002435 }
Winson9947f1e2019-08-16 10:20:39 -07002436 }
2437
Ryan Mitchelle2723072020-02-11 15:51:29 -08002438 if (oldLoaders.size() == newLoaders.size()) {
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002439 return;
2440 }
2441
Ryan Mitchelle2723072020-02-11 15:51:29 -08002442 mCallbacks.onLoadersChanged(this, newLoaders);
2443 for (int i = 0; i < loaders.length; i++) {
2444 loaders[i].unregisterOnProvidersChangedCallback(this);
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002445 }
Winson9947f1e2019-08-16 10:20:39 -07002446 }
2447 }
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002448
Ryan Mitchelle2723072020-02-11 15:51:29 -08002449 /**
2450 * Removes all {@link ResourcesLoader ResourcesLoader(s)}.
2451 * @hide
2452 */
2453 @VisibleForTesting
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002454 public void clearLoaders() {
Ryan Mitchelle2723072020-02-11 15:51:29 -08002455 synchronized (mUpdateLock) {
2456 checkCallbacksRegistered();
2457 final List<ResourcesLoader> newLoaders = Collections.emptyList();
2458 final List<ResourcesLoader> oldLoaders = mResourcesImpl.getAssets().getLoaders();
2459 mCallbacks.onLoadersChanged(this, newLoaders);
2460 for (ResourcesLoader loader : oldLoaders) {
2461 loader.unregisterOnProvidersChangedCallback(this);
2462 }
2463 }
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08002464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465}