Android Lint unused resource false positive - android

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.

Related

Using aar in Eclipse - why does the 3rd party activity resolve at build time but not run time?

I have a mature app that needs to have an SDK brought in that wraps the camera and makes it do some spiffy processing while it's running. The SDK has come to me in the form of some aar files but my app still lives in Eclipse. Because of my massive, steaming pile of a branding structure and deadlines for this integration the uncertain timeline required to fully migrate to Android Studio will not work (for now) so I'm going for converting the aars and using them in my app via Eclipse.
The problem I'm having is that I need to kick off the activity in the library but even though I fixed up all my build time reference problems, when running the app once I get to the point that is supposed to kick off the activity I get this error.
I've read through and double checked dozens of how-tos explaining how to consume the aar files and I think I've followed every step including:
Unzip the aar files and dress them up as individual library projects, including the file structure with the resources, the manifest, and the .jar
Make the project that needs the libraries add them as such
Add the .jars contained in the library projects to the build path (this step was not listed in most articles, and wasn't necessary for the project to build, but nevertheless it did not help my problem)
Declare the activity in your AndroidManifest.xml that the library brings in and declares in its AndroidManifest.xml
As I've said, everything looks good at build time, so I'm not sure what else to check. Because I'm reading that Gradle and Android Studio mashes manifests together really well, I have a hunch that it's something I'm supposed to regulate between the manifests but I don't know what it could be if that is it. I've wondered if I'm declaring the 3rd party's activity properly, but I'm not sure how to test it because the only way I can think to test it is to provide gibberish for the namespace but even then there are no complaints. I've also tried dissecting the .apk to look at the .dex file but I could not decipher anything useful.
My guess is that the library may not be building properly in eclipse - even before it's being added as a dependency to the application project.
Try looking at out/classes/* and making sure you have a .class file for the activity in question. I think the .class should actually be in the library as well as end up in the application project's out/ dir also.
If there are any native files (x.so) (as I would imagine there might be for spiffy camera stuff), you can look for the x.so files being included in the out/ dirs of both the library and application projects as well as the library.jar file.
Another option to maybe consider for this use case: https://github.com/ksoichiro/gradle-eclipse-aar-plugin
It seems that our app had a bad version of the appcompat-v7 support library. The .jars in it were different sizes than the one that comes with the SDK and several resources were missing. I have no idea how we ended up that way or where this bad version came from. Once I replaced it, things went great.
Later, I did encounter the need to drop in the .so files into the libraries I made that came out of the .aar files as Stad Kurdziel said in his answer, but that was causing a different error (the exception explicitly states that the .so is missing) and I arrived at the solution independently.

Different IDs are generated for the same resource in R classes

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

Why Android cannot deal with Resources name conflict between Project and Library?

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.

Using Activities from Library projects

I have a Library project set up and a project which depends on this library project - Everything compiles fine and I've had the Dependent project running fine however;
I'm have an intermittent problem however while using an Activity from the Library project.
My Library project can be "unchecked" as a library project and the "picker" Activity can be run in isolation. Running the Library project in it's own right works fine with no problems.
When I use the Library project (and the "picker" Activity) from the dependent project it gives me either NullPointerExceptions (or historically DexOp) errors saying that the "picker" Activity can't find it's resources.
Can anybody tell me if they have experienced this before?
EDIT
Manually copying the layout.xml used by the Library project activity to the dependent project makes the project open the "picker" Activity correctly. Is this required?! Surely not? This further makes me wonder if there is a problem with merging/referencing the integer id's from R.java in the Library project.
EDIT
I'm not sure if this is of any consequence, but one of my Library projects is a wrapper around a set of custom views used in different front end projects.
These custom views each have an Activity so that they can be tested in isolation.
One of these view's has custom attributes, which while running in isolation work very well. However, it doesn't seem like the dependent project correctly pull's in the attributes and keep's them in their original namespace, causing the imported layout's to throw compilation errors:
[2012-05-16 12:07:28 - Project] D:\opt\workspace\CustomGlowList\res\layout\main.xml:14: error: No resource identifier found for attribute 'listId' in package 'com.company.library.glowlist'
[2012-05-16 12:07:28 - Project] D:\opt\workspace\CustomGlowList\res\layout\main.xml:14: error: No resource identifier found for attribute 'type' in package 'com.company.library.glowlist
EDIT
DexOp errors were solved by removing a duplicate file name which was present in the Dependent project. Not sure if the file name was the problem or the contents of the file.
EDIT
I've been unable to find a solution to this problem as of yet (although #yorkw's answer certainly helps with the xml attributes! Thanks).
I have managed to make this problem intermittent however:
I have gone through each of the library projects and ensured they all had their own namespace (ie, com.company.library.component1, com.company.library.component2 etc). After a couple of clean's (each project ordered with the correct precedence) this problem resolves itself, however does eventually come back when switching around library/not a library to test components.
Cause:
Issue 9656: Library projects don't support custom XML attributes for custom classes
Solution:
Upgrade to latest SDK & ADT version (fixed was released since r17) and use http://schemas.android.com/apk/res-auto as custom attributes' namespace URI, see Revisions for ADT 17.0.0:
Added support for custom views with custom attributes in libraries. Layouts using custom attributes must use the namespace URI http://schemas.android.com/apk/res-auto instead of the URI that includes the app package name. This URI is replaced with the app specific one at build time.
Related Topic:
Help with a custom View attributes inside a Android Library Project
not sure how you use the android library , but i've done this thing a lot of times without any problems , so please have a reading of the next things regarding using android libraries:
in order for an android project to use an android library project , you can either edit the "project.properties" and add the path to the library project there , or , much easier, right click the project (that uses the library project) , choose "android" category , and choose there "add" and choose the library project.
in order to make the android project to always open the android library project , also choose "java build path"->"projects" and choose the library project.
on the "project.properties" , try to set the target to the same target for both projects , and to the newest one that you have (latest now is 15) ,even if you can't test the app on this android version .
source files and all resources files (in the res folder) are ok to be used on the library projects.
assets folders cannot be used inside the library project . only on the android project that actually runs , the assets folder can be used . same thing goes to the proguard file .
the manifest of the library projects almost doesn't need to have almost anything . see this post for more information: https://stackoverflow.com/a/10445630/878126 . if there are activities on the library project that you wish to be able to access via the project that use it , don't forget to include them in the manifest of the android project (no need to write them in the manifest of the android library) .
remember to run lint before you export the app . it gives you plenty of warnings , but the most important warning is when you use too-new functions that cannot run on the range of APIs that you target . this is important for libraries since it's easy to get lost if there are multiple sources .
if you wish to extend activities on the android library , you need some kind of a method to go between them . the only way i know of is to extend the application and let it be the manager of how to create an intent for each of the activities . i think you can do other tricks , but they are all probably similar to this one.
if you have the same resource (any resource on the "res" folder) on both the android library and the android project, the one on the android project will replace the other one . this has advantages and disadvantages . remember that you can't have different file extensions for the same resource .
The problem was being caused by the R files from each of the Library projects not correctly being built and referenced. The resource files are built and referenced directly from the calling project.
Each of the Libraries need to have unique package as defined in the AndroidManifest.xml. This leads to each of it's resources being compiled in that unique namespace within the calling project alongside the Library jar which contains the class files.
The problem becomes intermittent when switching between a library and a runnable project because a clean and build needs to take place to regenerate these files as it isn't done automagically when unclicking the Use as library checkbox, where as the jar (and java classes) don't require as much coaxing for them to be correctly referenced as the library projects references them when acting as a Library.
This can lead to intermittent and also varying errors including missing references, DexOp and NullPointerExceptions depending on to what degree the R.java files have been mangled or partially built and what conflicts are taking places between packages.
I have same issue like, I have one library project and it has some activity.
When I was calling library project's Activity from my Main project, layout files resources were not getting loaded properly for the libray project's activity and giving "nullpointer exception" or "class could not be loaded", etc.
Solution: I have noticed that same layout file name is getting used in my Library project and Main project. I have just renamed those activity and it is solved.
May be this will help you.
I had similar issue when referencing Library project inside the Android App project. I deleted the R.java file from Library project so it generated again and App picked up the generated file. You should see the generated R.java file under your app project->gen->library_namespace_R.java.

Multiple Projects from one Project with different ressource and config files

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.

Categories

Resources