Cannot override library's xml resource with png resource in application?
Asked Answered
D

3

20

I have an Android library MyLib containing everything I need for my app (targeting Android 2.2). This library has an XML resource:

drawable/main_background.xml

In my Application MyApp project I reference MyLib. Here I want to override specific resources (i.e. branding). So I added a background image in MyApp:

drawable/main_background.png

Eclipse keeps giving me this error:

[com.mycom.mylib.myapp] res\drawable\main_background.xml:0: error: Resource entry main_background is already defined.
[com.mycom.mylib.myapp] res\drawable\main_background.png:0: Originally defined here.

How can I override the resource in the library project?

Dorree answered 7/4, 2012 at 15:57 Comment(2)
have you got any solution to this problem yet?Bawcock
Sorry. I gave up on this. I finally made a png that looked like my xml. I'm still upset that I had to waste those kB :)Dorree
L
11

You cannot simply override resource ID (it's the resource ID you are overriding, not the actual file) with a file with different extension in Android SDK. However, you can do the trick by putting in your project xml file with the same name (main_background.xml) and fill it in a proper way to display your new file (main_background.png), which you need to rename earlier. All syntax you need is descibed here:

http://developer.android.com/guide/topics/resources/drawable-resource.html

, in your case it could be simply (assuming you put this in your non-library project as main_background.xml, and you have your new png as main_background_new.png):

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/main_background_new" />

With above solution, you could refer to @drawable/main_background from your project and it should use your file included with that project, instead of a library one.

Localize answered 28/8, 2012 at 7:52 Comment(4)
Hi, yes I understand this, it's similar to the example i posted in my answer, but the API states you have the ability to override resouce IDs (it doesn't comment on extensions), so, to be honest, I'm starting to think this is worthy of a bug report.Bawcock
Hi, Ive awarded you the bounty as you provided an improvement to the workaround i mentioned in my post. However, I am pretty sure that you /should/ be able to override resourceIDs regardless of the extension, so I think ill be submitting a bug report when i get timeBawcock
Thanks, but I don't think it will ever be possible, though - current system treats all resources from libraries and the project as they were from one project and use the same resource ID creation algorithm - it should be possible to include two files with the same name and different extension in one project, first.Localize
well whatever they have checking for duplicates is probably checking file names, they would just need to switch it to check resourceIDs.Bawcock
A
4
[com.mycom.mylib.myapp] res\drawable\main_background.xml:0: error: Resource entry main_background is already defined.
[com.mycom.mylib.myapp] res\drawable\main_background.png:0: Originally defined here.

I don't believe you can have the same file name even with different extensions. Try naming the png something else.

Now, i've not used overriding, So this seems odd as you'd expect this to be how you override the asset. However i think you've either got the two assets in your lib named the same. And that in your project it might be ok to have an asset with the same name. I would however check that its ok to have different types. XML is different than png, and if you access the asset from code you could get type errors.

Let me clarify the above point. I understand that a library project can have an item with the same Resource ID as an item in your application.

However the error above suggests that both main_background.png and main_background.xml are in the same project ([com.mycom.mylib.myapp]) which i don't believe is correct.

Further reading

This page describes the various types of project including the library project http://developer.android.com/tools/projects/index.html

Now i don't know where i got the impression from but having looked again it simply doesn't state anywhere that you can override a resource by using the same resource name. God knows why i thought that was a feature.

So no, the same rule applies as far as i can tell, that resources have to be named uniquely even across library projects, otherwise the generated resource ids will conflict. (The error your getting)

What is explained is how resource conflicts are managed.

Resource conflicts Since the tools merge the resources of a library project with those of a dependent application project, a given resource ID might be defined in both projects. In this case, the tools select the resource from the application, or the library with highest priority, and discard the other resource. As you develop your applications, be aware that common resource IDs are likely to be defined in more than one project and will be merged, with the resource from the application or highest-priority library taking precedence.

The system will use the resource with the highest priority, discarding everything else. Whats odd, is that you would think that a compile error wouldn't occur as the compiler should be discarding the resource. This makes me believe that the original poster had the similarly named assets in the same project, and not across the lib and project.

I haven't read anywhere that this is actually an intended feature. Got any links to say otherwise? (comment them)

Ambur answered 27/8, 2012 at 20:58 Comment(3)
Well it is supposed to be a 'feature' or at least a 'property' of library projects, as per your quote and the API quote in the bounty comment. It WILL work for resources with an identical name (including the extension), but that's not a resourceID - which is something you refer to in a layout.Bawcock
also, even if the OP did have the resources in the same project, I certainly didn't, and had the same problem. So if you get a compiler error with resources of the same name (but different extension) in different libraries, do you agree this should be reported as a Developer Tools bug?Bawcock
Yes, but I also know that there is an issue with Resource id's clashing between projects due to the way they are linked/setup, which is the issue, i just can't find the SO post that deals with it. Raise it as an issue.Ambur
B
3

So one 'solution' to this problem, which I do not consider to be an answer is the following:

Define an XML document in the library in question (we'll call it bunny.xml), and have it refer to another xml of a similar name (bunny_drawn.xml) with the actual content to be displayed.

Then, in the target project, override bunny.xml with another and use it to refer to an image with a different name instead - bunny_image.png

This does not however solve the problem, firstly because we aren't technically overriding a png with an xml (although the effect is somewhat close to that). Secondly because one of the key features of overriding resources is they are overridden, i.e. they are NOT compiled into the APK:

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

But the bunny_drawn.xml will still be compiled in! We can sort-of overcome the second point, by not only defining the image to be replaced in the target APP, but also replacing the old target bunny_drawn.xml with a blank xml. (or, as Fenix pointed out, you can have the contents of bunny_drawn.xml inside bunny.xml in the first case - the fact still remains that the resource ID can't be replaced...)

So my final conclusion is that this need to be submitted as a bug in the Developer Tools.

Bawcock answered 27/8, 2012 at 20:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.