10

I am reading docs about getResourceId() method. It says that:

Retrieves the resource identifier for the attribute at index. Note that attribute resource as resolved when the overall TypedArray object is retrieved. As a result, this function will return the resource identifier of the final resource value that was found, not necessarily the original resource that was specified by the attribute.

So

  • the first paragraph is clear:

Retrieves the resource identifier for the attribute at index.

  • the second is clear too:

Note that attribute resource as resolved when the overall TypedArray object is retrieved.

  • but what means the 3 paragraph? why it could return not necessarily the original resource id?

As a result, this function will return the resource identifier of the final resource value that was found, not necessarily the original resource that was specified by the attribute.

Viral Patel
  • 32,418
  • 18
  • 82
  • 110
GPack
  • 2,494
  • 4
  • 19
  • 50

2 Answers2

5

From the documentation:

TypedArray obtainStyledAttributes (AttributeSet set, 
                int[] attrs, 
                int defStyleAttr, 
                int defStyleRes)

....

When determining the final value of a particular attribute, there are four inputs that come into play:

  1. Any attribute values in the given AttributeSet.
  2. The style resource specified in the AttributeSet (named "style").
  3. The default style specified by defStyleAttr and defStyleRes
  4. The base values in this theme.
Kaamel
  • 1,852
  • 1
  • 19
  • 25
1

This is because Resource Merging needs to happen before the TypedArray is retrieved.

The Gradle-base build system uses a new merging mechanism for resources. In previous build system, merging was done by passing a list of resource folders to aapt which acted as overlays, alongside the --auto-add-overlay to ensure that new resources in the overlays would be automatically added (default behavior is for overlays is to only override existing resources, not create new ones).

One of the goals of the Gradle-based build system was providing more flexibility, and one frequently asked feature request was the ability to have more than one resources folders. aapt is not able to handle this so the new build system introduces a new merging mechanism that is run ahead of aapt and generates a single, merged, resources folder that is fed to aapt. This merging has the advantage of being incremental, both through Gradle's input/output change detection, and in the way it is implemented (ie it can rerun the merge by only applying the change in a single file).

The merged resources are coming from 3 types of sources:

  • The main resources, associated with the main sourceSet, generally located in src/main/res
  • The variant overlays, coming from the Build Type, and Flavor(s).
  • The Library Project dependencies, which contribute resources through the res entry in their aar bundle.

E.g. If you use different productFlavors or buildTypes you may have different resources for each flavor. So the one originally set at the time of development may be different from what is actually presented after changing the flavor.

Viral Patel
  • 32,418
  • 18
  • 82
  • 110