Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels) Summary: [Constants](https://developer.android.com/reference/java/util/ResourceBundle.Control#constants) \| [Fields](https://developer.android.com/reference/java/util/ResourceBundle.Control#lfields) \| [Protected Ctors](https://developer.android.com/reference/java/util/ResourceBundle.Control#proctors) \| [Methods](https://developer.android.com/reference/java/util/ResourceBundle.Control#pubmethods) \| [Inherited Methods](https://developer.android.com/reference/java/util/ResourceBundle.Control#inhmethods)

# ResourceBundle.Control

` public static class ResourceBundle.Control `   
` extends https://developer.android.com/reference/java/lang/Object ` ` `

|---|---|
| [java.lang.Object](https://developer.android.com/reference/java/lang/Object) ||
| ↳ | java.util.ResourceBundle.Control |

<br />

*** ** * ** ***

`ResourceBundle.Control` defines a set of callback methods that are invoked by the `https://developer.android.com/reference/java/util/ResourceBundle#getBundle(java.lang.String,%20java.util.Locale,%20java.lang.ClassLoader,%20java.util.ResourceBundle.Control)` factory methods during the bundle loading process. In other words, a `ResourceBundle.Control` collaborates with the factory methods for loading resource bundles. The default implementation of the callback methods provides the information necessary for the factory methods to perform the [default behavior](https://developer.android.com/reference/java/util/ResourceBundle.html#default_behavior).

In addition to the callback methods, the `https://developer.android.com/reference/java/util/ResourceBundle.Control#toBundleName(java.lang.String,%20java.util.Locale)` and `https://developer.android.com/reference/java/util/ResourceBundle.Control#toResourceName(java.lang.String,%20java.lang.String)` methods are defined primarily for convenience in implementing the callback methods. However, the `toBundleName` method could be overridden to provide different conventions in the organization and packaging of localized resources. The `toResourceName` method is `final` to avoid use of wrong resource and class name separators.

Two factory methods, `https://developer.android.com/reference/java/util/ResourceBundle.Control#getControl(java.util.List<java.lang.String>)` and `https://developer.android.com/reference/java/util/ResourceBundle.Control#getNoFallbackControl(java.util.List<java.lang.String>)`, provide `ResourceBundle.Control` instances that implement common variations of the default bundle loading process.

The formats returned by the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)` method and candidate locales returned by the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getCandidateLocales(java.lang.String,%20java.util.Locale)` method must be consistent in all `ResourceBundle.getBundle` invocations for the same base bundle. Otherwise, the `ResourceBundle.getBundle` methods may return unintended bundles. For example, if only `"java.class"` is returned by the `getFormats` method for the first call to `ResourceBundle.getBundle` and only `"java.properties"` for the second call, then the second call will return the class-based one that has been cached during the first call.

A `ResourceBundle.Control` instance must be thread-safe if it's simultaneously used by multiple threads. `ResourceBundle.getBundle` does not synchronize to call the `ResourceBundle.Control` methods. The default implementations of the methods are thread-safe.

Applications can specify `ResourceBundle.Control` instances returned by the `getControl` factory methods or created from a subclass of `ResourceBundle.Control` to customize the bundle loading process. The following are examples of changing the default bundle loading process.

**Example 1**

The following code lets `ResourceBundle.getBundle` look up only properties-based resources.

```
import java.util.*;
import static java.util.ResourceBundle.Control.*;
...
ResourceBundle bundle =
  ResourceBundle.getBundle("MyResources", new Locale("fr", "CH"),
                           ResourceBundle.Control.getControl(FORMAT_PROPERTIES));
```
Given the resource bundles in the [example](https://developer.android.com/reference/java/util/ResourceBundle.html#default_behavior_example) in the `ResourceBundle.getBundle` description, this `ResourceBundle.getBundle` call loads `MyResources_fr_CH.properties` whose parent is `MyResources_fr.properties` whose parent is `MyResources.properties`. (`MyResources_fr_CH.properties` is not hidden, but `MyResources_fr_CH.class` is.)

**Example 2**

The following is an example of loading XML-based bundles using `https://developer.android.com/reference/java/util/Properties#loadFromXML(java.io.InputStream)`.

```
ResourceBundle rb = ResourceBundle.getBundle("Messages",
    new ResourceBundle.Control() {
        public List<String> getFormats(String baseName) {
            if (baseName == null)
                throw new NullPointerException();
            return Arrays.asList("xml");
        }
        public ResourceBundle newBundle(String baseName,
                                        Locale locale,
                                        String format,
                                        ClassLoader loader,
                                        boolean reload)
                         throws IllegalAccessException,
                                InstantiationException,
                                IOException {
            if (baseName == null || locale == null
                  || format == null || loader == null)
                throw new NullPointerException();
            ResourceBundle bundle = null;
            if (format.equals("xml")) {
                String bundleName = toBundleName(baseName, locale);
                String resourceName = toResourceName(bundleName, format);
                InputStream stream = null;
                if (reload) {
                    URL url = loader.getResource(resourceName);
                    if (url != null) {
                        URLConnection connection = url.openConnection();
                        if (connection != null) {
                            // Disable caches to get fresh data for
                            // reloading.
                            connection.setUseCaches(false);
                            stream = connection.getInputStream();
                        }
                    }
                } else {
                    stream = loader.getResourceAsStream(resourceName);
                }
                if (stream != null) {
                    BufferedInputStream bis = new BufferedInputStream(stream);
                    bundle = new XMLResourceBundle(bis);
                    bis.close();
                }
            }
            return bundle;
        }
    });

...

private static class XMLResourceBundle extends ResourceBundle {
    private Properties props;
    XMLResourceBundle(InputStream stream) throws IOException {
        props = new Properties();
        props.loadFromXML(stream);
    }
    protected Object handleGetObject(String key) {
        return props.getProperty(key);
    }
    public Enumeration<String> getKeys() {
        ...
    }
}
```

<br />

## Summary

| ### Constants ||
|---|---|
| `long` | `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_DONT_CACHE` The time-to-live constant for not caching loaded resource bundle instances. |
| `long` | `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_NO_EXPIRATION_CONTROL` The time-to-live constant for disabling the expiration control for loaded resource bundle instances in the cache. |

| ### Fields ||
|---|---|
| ` public static final https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String>` | `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_CLASS` The class-only format `List` containing `"java.class"`. |
| ` public static final https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String>` | `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_DEFAULT` The default format `List`, which contains the strings `"java.class"` and `"java.properties"`, in this order. |
| ` public static final https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String>` | `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_PROPERTIES` The properties-only format `List` containing `"java.properties"`. |

| ### Protected constructors ||
|---|---|
| ` https://developer.android.com/reference/java/util/ResourceBundle.Control#Control()() ` Sole constructor. |

| ### Public methods ||
|---|---|
| ` https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/util/Locale>` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#getCandidateLocales(java.lang.String,%20java.util.Locale)(https://developer.android.com/reference/java/lang/String baseName, https://developer.android.com/reference/java/util/Locale locale) ` Returns a `List` of `Locale`s as candidate locales for `baseName` and `locale`. |
| ` static final https://developer.android.com/reference/java/util/ResourceBundle.Control` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#getControl(java.util.List<java.lang.String>)(https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String> formats) ` Returns a `ResourceBundle.Control` in which the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)` method returns the specified `formats`. |
| ` https://developer.android.com/reference/java/util/Locale` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#getFallbackLocale(java.lang.String,%20java.util.Locale)(https://developer.android.com/reference/java/lang/String baseName, https://developer.android.com/reference/java/util/Locale locale) ` Returns a `Locale` to be used as a fallback locale for further resource bundle searches by the `ResourceBundle.getBundle` factory method. |
| ` https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String>` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)(https://developer.android.com/reference/java/lang/String baseName) ` Returns a `List` of `String`s containing formats to be used to load resource bundles for the given `baseName`. |
| ` static final https://developer.android.com/reference/java/util/ResourceBundle.Control` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#getNoFallbackControl(java.util.List<java.lang.String>)(https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String> formats) ` Returns a `ResourceBundle.Control` in which the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)` method returns the specified `formats` and the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFallbackLocale(java.lang.String,%20java.util.Locale)` method returns `null`. |
| ` long` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#getTimeToLive(java.lang.String,%20java.util.Locale)(https://developer.android.com/reference/java/lang/String baseName, https://developer.android.com/reference/java/util/Locale locale) ` Returns the time-to-live (TTL) value for resource bundles that are loaded under this `ResourceBundle.Control`. |
| ` boolean` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#needsReload(java.lang.String,%20java.util.Locale,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.ResourceBundle,%20long)(https://developer.android.com/reference/java/lang/String baseName, https://developer.android.com/reference/java/util/Locale locale, https://developer.android.com/reference/java/lang/String format, https://developer.android.com/reference/java/lang/ClassLoader loader, https://developer.android.com/reference/java/util/ResourceBundle bundle, long loadTime) ` Determines if the expired `bundle` in the cache needs to be reloaded based on the loading time given by `loadTime` or some other criteria. |
| ` https://developer.android.com/reference/java/util/ResourceBundle` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#newBundle(java.lang.String,%20java.util.Locale,%20java.lang.String,%20java.lang.ClassLoader,%20boolean)(https://developer.android.com/reference/java/lang/String baseName, https://developer.android.com/reference/java/util/Locale locale, https://developer.android.com/reference/java/lang/String format, https://developer.android.com/reference/java/lang/ClassLoader loader, boolean reload) ` Instantiates a resource bundle for the given bundle name of the given format and locale, using the given class loader if necessary. |
| ` https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#toBundleName(java.lang.String,%20java.util.Locale)(https://developer.android.com/reference/java/lang/String baseName, https://developer.android.com/reference/java/util/Locale locale) ` Converts the given `baseName` and `locale` to the bundle name. |
| ` final https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/util/ResourceBundle.Control#toResourceName(java.lang.String,%20java.lang.String)(https://developer.android.com/reference/java/lang/String bundleName, https://developer.android.com/reference/java/lang/String suffix) ` Converts the given `bundleName` to the form required by the `https://developer.android.com/reference/java/lang/ClassLoader#getResource(java.lang.String)` method by replacing all occurrences of `'.'` in `bundleName` with `'/'` and appending a `'.'` and the given file `suffix`. |

### Inherited methods

From class ` https://developer.android.com/reference/java/lang/Object ` ` https://developer.android.com/reference/java/lang/Object` ` https://developer.android.com/reference/java/lang/Object#clone()() `

Creates and returns a copy of this object.
` boolean` ` https://developer.android.com/reference/java/lang/Object#equals(java.lang.Object)(https://developer.android.com/reference/java/lang/Object obj) `

Indicates whether some other object is "equal to" this one.
` void` ` https://developer.android.com/reference/java/lang/Object#finalize()() `

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
` final https://developer.android.com/reference/java/lang/Class<?>` ` https://developer.android.com/reference/java/lang/Object#getClass()() `

Returns the runtime class of this `Object`.
` int` ` https://developer.android.com/reference/java/lang/Object#hashCode()() `

Returns a hash code value for the object.
` final void` ` https://developer.android.com/reference/java/lang/Object#notify()() `

Wakes up a single thread that is waiting on this object's monitor.
` final void` ` https://developer.android.com/reference/java/lang/Object#notifyAll()() `

Wakes up all threads that are waiting on this object's monitor.
` https://developer.android.com/reference/java/lang/String` ` https://developer.android.com/reference/java/lang/Object#toString()() `

Returns a string representation of the object.
` final void` ` https://developer.android.com/reference/java/lang/Object#wait(long,%20int)(long timeoutMillis, int nanos) `

Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*, or until a certain amount of real time has elapsed.
` final void` ` https://developer.android.com/reference/java/lang/Object#wait(long)(long timeoutMillis) `

Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*, or until a certain amount of real time has elapsed.
` final void` ` https://developer.android.com/reference/java/lang/Object#wait()() `

Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*.

## Constants

### TTL_DONT_CACHE

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final long TTL_DONT_CACHE
```

The time-to-live constant for not caching loaded resource bundle instances.

<br />

**See also:**

- `https://developer.android.com/reference/java/util/ResourceBundle.Control#getTimeToLive(java.lang.String,%20java.util.Locale)`

Constant Value: -1 (0xffffffffffffffff)

### TTL_NO_EXPIRATION_CONTROL

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final long TTL_NO_EXPIRATION_CONTROL
```

The time-to-live constant for disabling the expiration control for loaded resource bundle instances in the cache.

<br />

**See also:**

- `https://developer.android.com/reference/java/util/ResourceBundle.Control#getTimeToLive(java.lang.String,%20java.util.Locale)`

Constant Value: -2 (0xfffffffffffffffe)

## Fields

### FORMAT_CLASS

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final List<String> FORMAT_CLASS
```

The class-only format `List` containing `"java.class"`. This `List` is unmodifiable.

<br />

**See also:**

- `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)`

### FORMAT_DEFAULT

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final List<String> FORMAT_DEFAULT
```

The default format `List`, which contains the strings `"java.class"` and `"java.properties"`, in this order. This `List` is unmodifiable.

<br />

**See also:**

- `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)`

### FORMAT_PROPERTIES

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final List<String> FORMAT_PROPERTIES
```

The properties-only format `List` containing `"java.properties"`. This `List` is unmodifiable.

<br />

**See also:**

- `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)`

## Protected constructors

### Control

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
protected Control ()
```

Sole constructor. (For invocation by subclass constructors, typically implicit.)

<br />

## Public methods

### getCandidateLocales

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public List<Locale> getCandidateLocales (String baseName, 
                Locale locale)
```

Returns a `List` of `Locale`s as candidate locales for `baseName` and `locale`. This method is called by the `ResourceBundle.getBundle` factory method each time the factory method tries finding a resource bundle for a target `Locale`.

The sequence of the candidate locales also corresponds to the runtime resource lookup path (also known as the *parent chain*), if the corresponding resource bundles for the candidate locales exist and their parents are not defined by loaded resource bundles themselves. The last element of the list must be a [root locale](https://developer.android.com/reference/java/util/Locale#ROOT) if it is desired to have the base bundle as the terminal of the parent chain.

If the given locale is equal to `Locale.ROOT` (the root locale), a `List` containing only the root `Locale` must be returned. In this case, the `ResourceBundle.getBundle` factory method loads only the base bundle as the resulting resource bundle.

It is not a requirement to return an immutable (unmodifiable) `List`. However, the returned `List` must not be mutated after it has been returned by `getCandidateLocales`.

The default implementation returns a `List` containing `Locale`s using the rules described below. In the description below, *L* , *S* , *C* and *V* respectively represent non-empty language, script, country, and variant. For example, \[*L* , *C* \] represents a `Locale` that has non-empty values only for language and country. The form *L* ("xx") represents the (non-empty) language value is "xx". For all cases, `Locale`s whose final component values are empty strings are omitted.

1. For an input `Locale` with an empty script value, append candidate `Locale`s by omitting the final component one by one as below:
   - \[*L* , *C* , *V*\]
   - \[*L* , *C*\]
   - \[*L*\]
   - `Locale.ROOT`
2. For an input `Locale` with a non-empty script value, append candidate `Locale`s by omitting the final component up to language, then append candidates generated from the `Locale` with country and variant restored:
   - \[*L* , *S* , *C* , *V*\]
   - \[*L* , *S* , *C*\]
   - \[*L* , *S*\]
   - \[*L* , *C* , *V*\]
   - \[*L* , *C*\]
   - \[*L*\]
   - `Locale.ROOT`
3. For an input `Locale` with a variant value consisting of multiple subtags separated by underscore, generate candidate `Locale`s by omitting the variant subtags one by one, then insert them after every occurrence of ` Locale`s with the full variant value in the original list. For example, if the variant consists of two subtags *V1* and *V2* :
   - \[*L* , *S* , *C* , *V1* , *V2*\]
   - \[*L* , *S* , *C* , *V1*\]
   - \[*L* , *S* , *C*\]
   - \[*L* , *S*\]
   - \[*L* , *C* , *V1* , *V2*\]
   - \[*L* , *C* , *V1*\]
   - \[*L* , *C*\]
   - \[*L*\]
   - `Locale.ROOT`
4. Special cases for Chinese. When an input `Locale` has the language "zh" (Chinese) and an empty script value, either "Hans" (Simplified) or "Hant" (Traditional) might be supplied, depending on the country. When the country is "CN" (China) or "SG" (Singapore), "Hans" is supplied. When the country is "HK" (Hong Kong SAR China), "MO" (Macau SAR China), or "TW" (Taiwan), "Hant" is supplied. For all other countries or when the country is empty, no script is supplied. For example, for `Locale("zh", "CN") `, the candidate list will be:
   - \[*L* ("zh"), *S* ("Hans"), *C*("CN")\]
   - \[*L* ("zh"), *S*("Hans")\]
   - \[*L* ("zh"), *C*("CN")\]
   - \[*L*("zh")\]
   - `Locale.ROOT`

   For `Locale("zh", "TW")`, the candidate list will be:
   - \[*L* ("zh"), *S* ("Hant"), *C*("TW")\]
   - \[*L* ("zh"), *S*("Hant")\]
   - \[*L* ("zh"), *C*("TW")\]
   - \[*L*("zh")\]
   - `Locale.ROOT`
5. Special cases for Norwegian. Both `Locale("no", "NO", "NY")` and `Locale("nn", "NO")` represent Norwegian Nynorsk. When a locale's language is "nn", the standard candidate list is generated up to \[*L* ("nn")\], and then the following candidates are added:
   - \[*L* ("no"), *C* ("NO"), *V*("NY")\]
   - \[*L* ("no"), *C*("NO")\]
   - \[*L*("no")\]
   - `Locale.ROOT`

   If the locale is exactly `Locale("no", "NO", "NY")`, it is first converted to `Locale("nn", "NO")` and then the above procedure is followed.

   Also, Java treats the language "no" as a synonym of Norwegian Bokmål "nb". Except for the single case `Locale("no", "NO", "NY")` (handled above), when an input `Locale` has language "no" or "nb", candidate `Locale`s with language code "no" and "nb" are interleaved, first using the requested language, then using its synonym. For example, `Locale("nb", "NO", "POSIX")` generates the following candidate list:
   - \[*L* ("nb"), *C* ("NO"), *V*("POSIX")\]
   - \[*L* ("no"), *C* ("NO"), *V*("POSIX")\]
   - \[*L* ("nb"), *C*("NO")\]
   - \[*L* ("no"), *C*("NO")\]
   - \[*L*("nb")\]
   - \[*L*("no")\]
   - `Locale.ROOT`

   `Locale("no", "NO", "POSIX")` would generate the same list except that locales with "no" would appear before the corresponding locales with "nb".

The default implementation uses an `https://developer.android.com/reference/java/util/ArrayList` that overriding implementations may modify before returning it to the caller. However, a subclass must not modify it after it has been returned by `getCandidateLocales`.

For example, if the given `baseName` is "Messages" and the given `locale` is `Locale("ja", "", "XX")`, then a `List` of `Locale`s:

```
    Locale("ja", "", "XX")
    Locale("ja")
    Locale.ROOT
```
is returned. And if the resource bundles for the "ja" and "" `Locale`s are found, then the runtime resource lookup path (parent chain) is:

    Messages_ja -> Messages

<br />

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base name of the resource bundle, a fully qualified class name <br /> |
| `locale` | `Locale`: the locale for which a resource bundle is desired <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/util/Locale>` | a `List` of candidate `Locale`s for the given `locale` <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `baseName` or `locale` is `null` |

### getControl

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final ResourceBundle.Control getControl (List<String> formats)
```

Returns a `ResourceBundle.Control` in which the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)` method returns the specified `formats`. The `formats` must be equal to one of `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_PROPERTIES`, `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_CLASS` or `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_DEFAULT`. `ResourceBundle.Control` instances returned by this method are singletons and thread-safe.

Specifying `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_DEFAULT` is equivalent to instantiating the `ResourceBundle.Control` class, except that this method returns a singleton.

<br />

| Parameters ||
|---|---|
| `formats` | `List`: the formats to be returned by the `ResourceBundle.Control.getFormats` method <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/util/ResourceBundle.Control` | a `ResourceBundle.Control` supporting the specified `formats` <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if `formats` is unknown |
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `formats` is `null` |

### getFallbackLocale

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public Locale getFallbackLocale (String baseName, 
                Locale locale)
```

Returns a `Locale` to be used as a fallback locale for further resource bundle searches by the `ResourceBundle.getBundle` factory method. This method is called from the factory method every time when no resulting resource bundle has been found for `baseName` and `locale`, where locale is either the parameter for `ResourceBundle.getBundle` or the previous fallback locale returned by this method.

The method returns `null` if no further fallback search is desired.

The default implementation returns the [default `Locale`](https://developer.android.com/reference/java/util/Locale#getDefault()) if the given `locale` isn't the default one. Otherwise, `null` is returned.

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base name of the resource bundle, a fully qualified class name for which `ResourceBundle.getBundle` has been unable to find any resource bundles (except for the base bundle) <br /> |
| `locale` | `Locale`: the `Locale` for which `ResourceBundle.getBundle` has been unable to find any resource bundles (except for the base bundle) <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/util/Locale` | a `Locale` for the fallback search, or `null` if no further fallback search is desired. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `baseName` or `locale` is `null` |

### getFormats

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public List<String> getFormats (String baseName)
```

Returns a `List` of `String`s containing formats to be used to load resource bundles for the given `baseName`. The `ResourceBundle.getBundle` factory method tries to load resource bundles with formats in the order specified by the list. The list returned by this method must have at least one `String`. The predefined formats are `"java.class"` for class-based resource bundles and `"java.properties"` for [properties-based](https://developer.android.com/reference/java/util/PropertyResourceBundle) ones. Strings starting with `"java."` are reserved for future extensions and must not be used by application-defined formats.

It is not a requirement to return an immutable (unmodifiable) `List`. However, the returned `List` must not be mutated after it has been returned by `getFormats`.

The default implementation returns `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_DEFAULT` so that the `ResourceBundle.getBundle` factory method looks up first class-based resource bundles, then properties-based ones.

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base name of the resource bundle, a fully qualified class name <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/lang/String>` | a `List` of `String`s containing formats for loading resource bundles. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `baseName` is null |

**See also:**

- `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_DEFAULT`
- `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_CLASS`
- `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_PROPERTIES`

### getNoFallbackControl

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final ResourceBundle.Control getNoFallbackControl (List<String> formats)
```

Returns a `ResourceBundle.Control` in which the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFormats(java.lang.String)` method returns the specified `formats` and the `https://developer.android.com/reference/java/util/ResourceBundle.Control#getFallbackLocale(java.lang.String,%20java.util.Locale)` method returns `null`. The `formats` must be equal to one of `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_PROPERTIES`, `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_CLASS` or `https://developer.android.com/reference/java/util/ResourceBundle.Control#FORMAT_DEFAULT`. `ResourceBundle.Control` instances returned by this method are singletons and thread-safe.

<br />

| Parameters ||
|---|---|
| `formats` | `List`: the formats to be returned by the `ResourceBundle.Control.getFormats` method <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/util/ResourceBundle.Control` | a `ResourceBundle.Control` supporting the specified `formats` with no fallback `Locale` support <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if `formats` is unknown |
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `formats` is `null` |

### getTimeToLive

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public long getTimeToLive (String baseName, 
                Locale locale)
```

Returns the time-to-live (TTL) value for resource bundles that are loaded under this `ResourceBundle.Control`. Positive time-to-live values specify the number of milliseconds a bundle can remain in the cache without being validated against the source data from which it was constructed. The value 0 indicates that a bundle must be validated each time it is retrieved from the cache. `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_DONT_CACHE` specifies that loaded resource bundles are not put in the cache. `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_NO_EXPIRATION_CONTROL` specifies that loaded resource bundles are put in the cache with no expiration control.

The expiration affects only the bundle loading process by the `ResourceBundle.getBundle` factory method. That is, if the factory method finds a resource bundle in the cache that has expired, the factory method calls the `https://developer.android.com/reference/java/util/ResourceBundle.Control#needsReload(java.lang.String,%20java.util.Locale,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.ResourceBundle,%20long)` method to determine whether the resource bundle needs to be reloaded. If `needsReload` returns `true`, the cached resource bundle instance is removed from the cache. Otherwise, the instance stays in the cache, updated with the new TTL value returned by this method.

All cached resource bundles are subject to removal from the cache due to memory constraints of the runtime environment. Returning a large positive value doesn't mean to lock loaded resource bundles in the cache.

The default implementation returns `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_NO_EXPIRATION_CONTROL`.

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base name of the resource bundle for which the expiration value is specified. <br /> |
| `locale` | `Locale`: the locale of the resource bundle for which the expiration value is specified. <br /> |

| Returns ||
|---|---|
| `long` | the time (0 or a positive millisecond offset from the cached time) to get loaded bundles expired in the cache, `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_NO_EXPIRATION_CONTROL` to disable the expiration control, or `https://developer.android.com/reference/java/util/ResourceBundle.Control#TTL_DONT_CACHE` to disable caching. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `baseName` or `locale` is `null` |

### needsReload

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public boolean needsReload (String baseName, 
                Locale locale, 
                String format, 
                ClassLoader loader, 
                ResourceBundle bundle, 
                long loadTime)
```

Determines if the expired `bundle` in the cache needs to be reloaded based on the loading time given by `loadTime` or some other criteria. The method returns `true` if reloading is required; `false` otherwise. `loadTime` is a millisecond offset since the [`Calendar` Epoch](https://developer.android.com/reference/java/util/Calendar#Epoch).

The calling `ResourceBundle.getBundle` factory method calls this method on the `ResourceBundle.Control` instance used for its current invocation, not on the instance used in the invocation that originally loaded the resource bundle.

The default implementation compares `loadTime` and the last modified time of the source data of the resource bundle. If it's determined that the source data has been modified since `loadTime`, `true` is returned. Otherwise, `false` is returned. This implementation assumes that the given `format` is the same string as its file suffix if it's not one of the default formats, `"java.class"` or `"java.properties"`.

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base bundle name of the resource bundle, a fully qualified class name <br /> |
| `locale` | `Locale`: the locale for which the resource bundle should be instantiated <br /> |
| `format` | `String`: the resource bundle format to be loaded <br /> |
| `loader` | `ClassLoader`: the `ClassLoader` to use to load the bundle <br /> |
| `bundle` | `ResourceBundle`: the resource bundle instance that has been expired in the cache <br /> |
| `loadTime` | `long`: the time when `bundle` was loaded and put in the cache <br /> |

| Returns ||
|---|---|
| `boolean` | `true` if the expired bundle needs to be reloaded; `false` otherwise. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `baseName`, `locale`, `format`, `loader`, or `bundle` is `null` |

### newBundle

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public ResourceBundle newBundle (String baseName, 
                Locale locale, 
                String format, 
                ClassLoader loader, 
                boolean reload)
```

Instantiates a resource bundle for the given bundle name of the given format and locale, using the given class loader if necessary. This method returns `null` if there is no resource bundle available for the given parameters. If a resource bundle can't be instantiated due to an unexpected error, the error must be reported by throwing an `Error` or `Exception` rather than simply returning `null`.

If the `reload` flag is `true`, it indicates that this method is being called because the previously loaded resource bundle has expired.

The default implementation instantiates a `ResourceBundle` as follows.

- The bundle name is obtained by calling `https://developer.android.com/reference/java/util/ResourceBundle.Control#toBundleName(java.lang.String,%20java.util.Locale)`.
- If `format` is `"java.class"`, the `https://developer.android.com/reference/java/lang/Class` specified by the bundle name is loaded with the given class loader. If the `Class` is found and accessible then the `ResourceBundle` is instantiated. The resource bundle is accessible if the package of the bundle class file is open unconditionally; otherwise, `IllegalAccessException` will be thrown. Note that the `reload` flag is ignored for loading class-based resource bundles in this default implementation.
- If `format` is `"java.properties"`, `https://developer.android.com/reference/java/util/ResourceBundle.Control#toResourceName(java.lang.String,%20java.lang.String)` is called to get the resource name. If `reload` is `true`, `https://developer.android.com/reference/java/lang/ClassLoader#getResource(java.lang.String)` is called to get a `https://developer.android.com/reference/java/net/URL` for creating a `https://developer.android.com/reference/java/net/URLConnection`. This `URLConnection` is used to [disable the caches](https://developer.android.com/reference/java/net/URLConnection#setUseCaches(boolean)) of the underlying resource loading layers, and to [get an `InputStream`](https://developer.android.com/reference/java/net/URLConnection#getInputStream()). Otherwise, `https://developer.android.com/reference/java/lang/ClassLoader#getResourceAsStream(java.lang.String)` is called to get an `https://developer.android.com/reference/java/io/InputStream`. Then, a `https://developer.android.com/reference/java/util/PropertyResourceBundle` is constructed with the `InputStream`.
- If `format` is neither `"java.class"` nor `"java.properties"`, an `IllegalArgumentException` is thrown.

<br />

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base bundle name of the resource bundle, a fully qualified class name <br /> |
| `locale` | `Locale`: the locale for which the resource bundle should be instantiated <br /> |
| `format` | `String`: the resource bundle format to be loaded <br /> |
| `loader` | `ClassLoader`: the `ClassLoader` to use to load the bundle <br /> |
| `reload` | `boolean`: the flag to indicate bundle reloading; `true` if reloading an expired resource bundle, `false` otherwise <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/util/ResourceBundle` | the resource bundle instance, or `null` if none could be found. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/io/IOException` | if an error occurred when reading resources using any I/O operations |
| `https://developer.android.com/reference/java/lang/ClassCastException` | if the loaded class cannot be cast to `ResourceBundle` |
| `https://developer.android.com/reference/java/lang/ExceptionInInitializerError` | if the initialization provoked by this method fails. |
| `https://developer.android.com/reference/java/lang/IllegalAccessException` | if the class or its nullary constructor is not accessible. |
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if `format` is unknown, or if the resource found for the given parameters contains malformed data. |
| `https://developer.android.com/reference/java/lang/InstantiationException` | if the instantiation of a class fails for some other reason. |
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `bundleName`, `locale`, `format`, or `loader` is `null`, or if `null` is returned by `https://developer.android.com/reference/java/util/ResourceBundle.Control#toBundleName(java.lang.String,%20java.util.Locale)` |
| `https://developer.android.com/reference/java/lang/SecurityException` | If a security manager is present and creation of new instances is denied. See `https://developer.android.com/reference/java/lang/Class#newInstance()` for details. |

### toBundleName

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public String toBundleName (String baseName, 
                Locale locale)
```

Converts the given `baseName` and `locale` to the bundle name. This method is called from the default implementation of the `https://developer.android.com/reference/java/util/ResourceBundle.Control#newBundle(java.lang.String,%20java.util.Locale,%20java.lang.String,%20java.lang.ClassLoader,%20boolean)` and `https://developer.android.com/reference/java/util/ResourceBundle.Control#needsReload(java.lang.String,%20java.util.Locale,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.ResourceBundle,%20long)` methods.

This implementation returns the following value:

```
    baseName + "_" + language + "_" + script + "_" + country + "_" + variant
```
where `language`, `script`, `country`, and `variant` are the language, script, country, and variant values of `locale`, respectively. Final component values that are empty Strings are omitted along with the preceding '_'. When the script is empty, the script value is omitted along with the preceding '_'. If all of the values are empty strings, then `baseName` is returned.

For example, if `baseName` is `"baseName"` and `locale` is `Locale("ja", "", "XX")`, then `"baseName_ja_ _XX"` is returned. If the given locale is `Locale("en")`, then `"baseName_en"` is returned.

Overriding this method allows applications to use different conventions in the organization and packaging of localized resources.

<br />

| Parameters ||
|---|---|
| `baseName` | `String`: the base name of the resource bundle, a fully qualified class name <br /> |
| `locale` | `Locale`: the locale for which a resource bundle should be loaded <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | the bundle name for the resource bundle <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `baseName` or `locale` is `null` |

### toResourceName

Added in [API level 9](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public final String toResourceName (String bundleName, 
                String suffix)
```

Converts the given `bundleName` to the form required by the `https://developer.android.com/reference/java/lang/ClassLoader#getResource(java.lang.String)` method by replacing all occurrences of `'.'` in `bundleName` with `'/'` and appending a `'.'` and the given file `suffix`. For example, if `bundleName` is `"foo.bar.MyResources_ja_JP"` and `suffix` is `"properties"`, then `"foo/bar/MyResources_ja_JP.properties"` is returned.

<br />

| Parameters ||
|---|---|
| `bundleName` | `String`: the bundle name <br /> |
| `suffix` | `String`: the file type suffix <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | the converted resource name <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/NullPointerException` | if `bundleName` or `suffix` is `null` |