7

I have two Android projects, a main one (package name com.adip.sampler) and a library that is added to main (package name com.samples.projb). In both of them in resources I have an integer-array with same key: my_int_values:

In main project:

<integer-array name="my_int_values">
    <item>10</item>
    <item>20</item>
    <item>30</item>
    <item>40</item>
    <item>50</item>
    <item>60</item>
    <item>70</item>
    <item>80</item>
</integer-array>

while in library:

<integer-array name="my_int_values">
    <item>34</item>
    <item>35</item>
    <item>36</item>
    <item>37</item>
</integer-array>

In main project from an activity if I am investigating what are the values from these arrays (both main project and library):

protected void showLocalStrings() {
    Log.d("RESSampler", "In Main: " + Arrays.toString(getResources().getIntArray(com.adip.sampler.R.array.my_int_values)));
    Log.d("RESSampler", "In Libr: " + Arrays.toString(getResources().getIntArray(com.samples.projb.R.array.my_int_values)));
}

then I'm seeing this in Logcat:

In Main: [10, 20, 30, 40, 50, 60, 70, 80]
In Libr: [10, 20, 30, 40, 50, 60, 70, 80]

It seems that main project is overriding the values defined in library array ... I doubled checked if I am reading from resources with correct key and that is ok. Until I took a look in each generated R class. In the main project this is what I have for com.adip.sampler.R.array.my_int_values:

public static final class array {
    public static final int my_int_values=0x7f060000;
}

while in library project com.samples.projb.R.array.my_int_values:

public static final class array {
    public static final int my_int_values = 0x7f060000;
}

Android tool has generated the same value, so no wonder I am getting this behavior. I can get rid of this behavior if I change the key from one of the integer arrays, but imagine that you have some big projects with a lot of resources, dependency libraries and sooner or later you may bump into this kind of issue: having the same type of resources with the same key value (I've checked with string and with string-array and above behavior appears there as well). So the questions would be:

  1. Why this issue appears? Or if it's not an issue what explains this behavior?
  2. How to avoid it best? I am guessing that trying to have some kind of uniqueness in defining the keys will do the trick, but developers tend to be lazy ...

This appears using multiple variants of latest ADTs and Eclipse versions (Juno and Indigo). Checked on Windows only.

gunar
  • 14,660
  • 7
  • 56
  • 87

2 Answers2

10

Reading from Library Projects at Android Developers, there are many references where they clearly say merging happens at build time and resources with same IDs overwrite each other.

For resources with same ID from a library and application

In cases where a resource ID is defined in both the application and the library, the tools ensure that the resource declared in the application gets priority and that the resource in the library project is not compiled into the application .apk. This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library.

For resources with same ID from two libraries

... your application can add references to multiple library projects, then specify the relative priority of the resources in each library. This lets you build up the resources actually used in your application in a cumulative manner. When two libraries referenced from an application define the same resource ID, the tools select the resource from the library with higher priority and discard the other.

Solution suggested in documentation

Use prefixes to avoid resource conflicts

To avoid resource conflicts for common resource IDs, consider using a prefix or other consistent naming scheme that is unique to the project (or is unique across all projects).

How to set priority in libraries from command line

If you are adding references to multiple libraries, note that you can set their relative priority (and merge order) by manually editing the project.properties file and adjusting the each reference's .n index as appropriate.

auselen
  • 27,577
  • 7
  • 73
  • 114
  • I was afraid that this is the answer :) Do you happen to know if Lint has a mean to detect duplicate resource ids across different projects? – gunar Oct 14 '13 at 07:51
  • 1
    Comment on `This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library` I really don't see any flexibility here. If Android is using the resource from main project or from higher priority project and dumping the duplicate resource, where is the flexibility? – gunar Oct 14 '13 at 07:53
  • Accepted answer, but StackOverflow allows me to give the bounty only in 22 hrs. tack så mycket! – gunar Oct 14 '13 at 07:55
  • @gunar "varså god". My personal impression is all these flexibility is there because tools work in that way anyway. I mean they first wrote the tools then defined the rules :). – auselen Oct 14 '13 at 08:23
  • @gunar flexibility is you can overwrite. – auselen Oct 14 '13 at 08:23
  • @gunar I don't know if there are existing rules. It should be possible to write some Lint rules - it makes sense, however I never tried that. – auselen Oct 14 '13 at 08:24
1

Personally, I would change the names of the resources. If you read anything about naming conventions, it should be something meaningful and "my_int_array" isn't really too helpful, especially in a library that other people or project could potentially use.

Ideally, you want to be able to forget about this for 6 months, come back and look at it and know what that array is for/contains, without having to delve through code to deduce what the array is for by what's done with it.

This post; https://stackoverflow.com/a/7249410/1222199 contains a few different answers on naming conventions.

Finally, not sure about the conflict, couldn't dig anything up. I'm guessing it's to do with the way it's automatically generated, might be worth logging it as a bug and see if you get any response from the development team.

Community
  • 1
  • 1
Trent
  • 1,595
  • 15
  • 37
  • I guess you realize `my_int_array` and this project is something made up for for this question clarity. I am dealing with a huge project having 5 other library projects and each is another medium project with its own resources. I'm hunting duplicate resource keys and changing wherever those are used. But it would be great to know WHY this is happening. Why the build system isn't generating unique keys across a workspace / project eco-system? – gunar Oct 14 '13 at 06:57
  • Yeah, I do. Still, there must be a better naming system that you can come up with so that they are unique, a current project I have is made up of 10 separate projects, only some of which I control. I imagine that adding/removing a single character would be enough to change the key. Obviously the algorithm used doesn't work at a workspace level, only a project level, hence the suggestion to log this as a bug. In all honesty, it's probably going to be a very rare occurrence that this happens. The fact that there is little to no information on the matter reinforces how rare an occurrence this is. – Trent Oct 14 '13 at 07:06