The Android implementation retrieves the resource ID by name

  • 2020-06-12 10:36:00
  • OfStack

Those of you who have been exposed to Android development know that access to program resources in Android is basically through ID. This is easy to develop and allows you to explicitly specify resources without considering the various resolutions, languages, and so on.

Pain points

Sometimes, however, there will be 1 some problems, such as the value according to the server we collect the pictures, but never returned to the us is on the server resource id, is one kind of most value associated with the file name, less operating resources, can maintain a container for value and resources ID mapping, but much, will need to find a way to another.

Easy way

In this case, using the file name to get the resource ID is twice the effort. The resource ID can be easily obtained by calling getIdentifier of Resources. A few simple examples:


Resources res = getResources();
final String packageName = getPackageName();
int imageResId = res.getIdentifier("ic_launcher", "drawable", packageName);
int imageResIdByAnotherForm = res.getIdentifier(packageName + ":drawable/ic_launcher", null, null);
 
int musicResId = res.getIdentifier("test", "raw", packageName);
     
int notFoundResId = res.getIdentifier("activity_main", "drawable", packageName); Log.i(LOGTAG, "testGetResourceIds imageResId = " + imageResId
              + ";imageResIdByAnotherForm = " + imageResIdByAnotherForm
              + ";musicResId=" + musicResId
              + ";notFoundResId =" + notFoundResId);

The results


I/MainActivity( 4537): testGetResourceIds imageResId = 2130837504;imageResIdByAnotherForm = 2130837504;musicResId=2130968576;notFoundResId =0

See 1 API

Direct API

1. This method is used to get the resource ID using the resource name
2. The full resource name is package:type/entry. If the resource name parameter is fully specified, defType and defPackage can be omitted.
When defType and defPackage are omitted, it needs to be set to null
4. Note that this approach is not recommended as it would be more efficient to access resources directly through ID
5. If the resource is not found, return 0, in Android resource ID 0 is not a valid resource ID.


**
     * Return a resource identifier for the given resource name.  A fully
     * qualified resource name is of the form "package:type/entry".  The first
     * two components (package and type) are optional if defType and
     * defPackage, respectively, are specified here.
     *
     * <p>Note: use of this function is discouraged.  It is much more
     * efficient to retrieve resources by identifier than by name.
     *
     * @param name The name of the desired resource.
     * @param defType Optional default resource type to find, if "type/" is
     *                not included in the name.  Can be null to require an
     *                explicit type.
     * @param defPackage Optional default package to find, if "package:" is
     *                   not included in the name.  Can be null to require an
     *                   explicit package.
     *
     * @return int The associated resource identifier.  Returns 0 if no such
     *         resource was found.  (0 is not a valid resource ID.)
     */
    public int getIdentifier(String name, String defType, String defPackage) {
        try {
            return Integer.parseInt(name);
        } catch (Exception e) {
            // Ignore
        }
        return mAssets.getResourceIdentifier(name, defType, defPackage);
    }

Indirect API

In fact, the above API calls the native method in AssetManager.class.


/**
     * Retrieve the resource identifier for the given resource name.
     */
    /*package*/ native final int getResourceIdentifier(String type,
                                                       String name,
                                                       String defPackage);


Related articles: