When a project with one of more apk libs is compiled, then more then one R.java is generated by the aapt tool. One for each library and one for the application itself.
Each of those R files would define the same IDs. This worked without problems for quite a while now. Years in fact. But suddenly not any more. Now the same resource has two different IDs.
target/generated-sources/r/com/viewpagerindicator/R.java:
public static int default_line_indicator_selected_color=0x7f04000b;
target/generated-sources/r/net/sourceforge/uiq3/fx602p/R.java:
public static final int default_line_indicator_selected_color=0x7f07000b;
Has anybody got an idea what might have gone wrong?
Update:
I double checked with other projects. There I noted that apart from the final the R.java files should be 100% identical. Especially: each R.java file should define all IDs — Even the IDs which are not part of a library.
This too is not the case in my troublesome project. Each library R.java only defines the IDs used by the library.
Quick and Dirty Fix
Until i find out what the real problem I use the following ant task as a quick and dirty fix:
<copy
encoding='${project.build.sourceEncoding}'
file='target/generated-sources/r/net/sourceforge/uiq3/fx602p/R.java'
overwrite='true'
toFile='target/generated-sources/r/com/viewpagerindicator/R.java'
>
<filterchain>
<tokenfilter>
<replacestring
from='net.sourceforge.uiq3.fx602p'
to='com.viewpagerindicator'
></replacestring>
</tokenfilter>
</filterchain>
</copy>
I wonder why aapt is called several times when a copy with search and replace can do the trick as well. And note that i don't remove the final as well.
When you assemble the project, the library ressource are overwritten by the main project.
I think this explain why the R ids in library aren't final.
All your references to default_line_indicator_selected_color will use the new value 0x7f07000b.
In what situation do you have problems with this?
When you build an application that depends on a library project, the SDK tools compile the library into a temporary JAR file and uses it in the main project, then uses the result to generate the .apk. 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.
http://developer.android.com/tools/projects/index.html
Related
Migrating from eclipse to Android Studio. Here is AS's build dir structure
Question 1. Where does gradle put all the compiled .class files? Is it the projectRoot/build/intermediates/classes directory?
The purpose of this question is a Java class is generated at build time (eg: CustomBuildInfo.java) and needs to added to the complied dir so that other src files can use it and packaged correctly within APK.
Note:Previously in Eclipse this generated file use to reside inside projectRoot/gen/<package> directory.
Question 2. Whats the correct location for custom generated Java files? Is it build/generated/r/<buildType>/<package> ? (this is where R.java resides)
Note But this custom generated Java file CustomBuildInfo.java belongs to common source i.e., used by all build types and all flavors
Any help will be appreciated.
To answer my own question when using GRADLE build system
Java Byte Code location (post-compilation) <projectroot>/build/intermediates/classes/<build-type>/....
assets
<projectroot>/build/intermediates/assets/<build-type>/....
res
<projectroot>/build/intermediates/res/merged/<build-type>/....
JNI libs (configurable)
<projectroot>/build/intermediates/jniLibs/<build-type>/....
Manifests
<projectroot>/build/intermediates/manifests/full/<build-type>/....
Java class generated from AIDL
<projectroot>/build/generated/source/aidl/<build-type>/....
R.java
<projectroot>/build/generated/source/r/<build-type>/....
BuildConfig.java
<projectroot>/build/generated/source/buildConfig/<build-type>/....
Test reports HTML
<projectroot>/build/reports/tests/<build-type>/index.html
APK output files
<projectroot>/build/outputs/apk/...
Lint Results
<projectroot>/build/outputs/...
Manifest Merger Report (if using multi-module build)
<projectroot>/build/outputs/logs/...
Test Results
<projectroot>/build/test-results/...
Intermediate classes can sometimes be stored at "../build/intermediates/javac/debug/compileDebugJavaWithJavac/classes" for the debug build classes and at "../build/intermediates/javac/relese/compileReleaseJavaWithJavac/classes" for the release build classes. And sometimes they can be stored at "../build/debug" for debug classes and at "../build/release" for release build classes.
I'm not sure what causes them to be in one place or the other. If you look at the ".impl" file (which contains xml) for the module your interested in you will find an entry like this:
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes" />
or an enty like this:
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
That's what determines where the intermediate classes will be stored for the module. Why it's sometimes in the 'build/intermediate/classes' directory and sometimes in the 'build/intermediate/java' directory has me baffled. I've look for various reasons such as 1.) is it affected by the manisfest, 2.) manifest merging 3.) jdk version 4.) module type (application, android library, java library), 5.) use of instance run. In all my attempts to see what causes it to choice one or the other, I've not been able to determine how that decision is made. If someone knows what factor determines the directory scheme choice , please add the reason.
If you're like me and have a reason want to get access to the intermediate java classes produced, the easiest work around is to see which directory exist. You'll have one or the other, but not both!
I have been getting this strange warning in Eclipse. I'm not sure how to reproduce this error but here is what I have:
One library project with code and no resources
Two library project with resources and code
One app project with resources and code that depends on the above libraries
One library project with resources and no code that depends on the above libraries
Two app projects with code and no resources that depend on all the libraries above
The thing is that I'm getting this warning:
The resource R.drawable.background appears to be unused
But this resource is inside the second library project with resources and code and it is used in the last library project with resources and no code and the last two apps. But this warning is showed to be in the very first library project with no resources, that doesn't even depend on the library that has the resource. Any ideas? I can't even add a supress warning since Lint doesn't even say where the file is. Even though I know where it is.
I have a project A that referenced by Library B, A and B have the same name and type, but their value are different. I think aapt should deal with this issue that make sure project and library access the correct value. besides renaming all the resource in project or library, what else should I do to solve this problem?
The build system intentionally makes all project resources overlay on top of the library resources. This is done on purpose to be able to customize a library resource differently depending on the app using it.
If you want to prevent this happening without your knowledge we have always recommended users to use prefix in the library resources.
Changing the behavior at this point would break many, many people's projects. We've looked at making it an option, but it won't happen before the new build system is finished though.
As per the Android Building process, all projects and libraries (and all of the resources in all of them) are combined as part of the apkbuilder process. If there is a conflict between your project and library (or between two libraries), the final build will not know which to reference as they share the same name. Of course, this has benefits in that you can reference library resources in your project by name, even though the underlying build process is de-conflicting the underlying ids.
Import the appropriate R.java file to resolve the resource conflicts.
Make sure that your package name and the library's package names are different.
If you need your libraries resources then refer to them by library.packagename.R.drawable.resourceId and not by R.drawable.resourceId
Check your gen files if it has 2 R.java files.
I am trying to create a android project with two libraries,however, I have been able to link the two libraries I created with my android project.
I have same xml name in two libbaries,when I am compiling my project, the R.java file is getting compiled in my new project and I am getting only one xml file from the two libraries. how could I link the two libraries in my android project with the same xml names? I know it can be done with diff names but I want the same name.
Are you saying you have say strings.xml in /res/values in both library projects and expect to get more than one strings.xml in your consuming project?
From what I experience, if I have strings.xml in library projects and also in my consuming project, the resulting R.java will have the values from all 3 merged together, with any duplicate entries having the value as defined in the consuming project.
Not possible. That's the way library projects are designed to work. Resources are merged into the parent project. If you want values from both libraries to make it in, they need to have different resource IDs, and even then you'll have one resource file (unless you have different file names to start with).
The only way you could get this to "work" is to do something with your build process renaming the files, which is doable, but not trivial, especially if there are possible resource ID conflicts and even harder if your main project needs to use any of those resources directly.
I have one Project let us say pattern project. There are all sources and layouts for the different versions of the other projects. Without the drawables, because the other projects have different.
There are also 2 projects which use this pattern project es library. Which has there own drawable ressources and some own layout xml files.
This is working for me, I can compile it and on the device it is running.
But every time the workspace is building I get a lot of errors from the pattern project that there are no ressoruce files which are uses in the layout xml files.
res\layout\news_list.xml:9: error: Error: No resource found that matches the given name (at 'src' with value '#drawable/logosmall').
Is this normal? I'm using the wrong way to do it? How can I fix this?
I hope anyone of you can help me.
A Library project is treated as a normal Android project by the build process, so if you want it to build without errors you have to include all referenced resources (or at least similarly named placeholders) in the Library project itself even if they are to be "overridden" by your application projects.