Android’s R class is a very handy way of externalizing resources. It’s also for the most part pretty intuitive, which is a good thing because its use is practically mandatory in order to do anything interesting with Android. Recently, though, I ran into a strange issue where Eclipse would claim not to be able to resolve a reference to it. As an example, here is the code I would use to load an OpenGL ES 2 shader program:
// Create shader, get handle to its compiled program
shader = new ShaderProgram(R.raw.vs, R.raw.fs);
mProgram = shader.getProgram();
The constructor in the above snippet takes two int’s; each is internally passed to an Android framework method that uses the int to load the shader text file (in this case, <project>/res/vs.glsl is the path to the vertex shader, and similarly fs.glsl for the fragment shader.) By having put those two .glsl files into the /res/ folder, the Android SDK should more or less automatically generate the appropriate ID necessary to find them; it works perfectly for me most of the time.
However, when I pulled this line of code into a different project, Eclipse threw the following error:
R cannot be resolved
No further details are given for this error. The ints were generated and did exist (verifiable in Eclipse by accessing the ‘gen’ directory in your project.) It turns out there were a few things that needed to be resolved to convince Eclipse of that, though.
It turned out in the making of this project, I had attempted to rename the application’s package. I did this the way I normally would when working on a Java project in Eclipse: right clicking the project name and then Refactor > Rename. Generally Eclipse handles this type of thing pretty well, but package names need to be changed in several more places in an Android project:
- Any source files
- The ‘gen’ folder has its own package
- Probably others
So, rather than trying to hunt down every instance of the package name and trying to make them all match, a better idea is to right click the project name, and choose Android Tools > Rename Application Package. This function actually even fixed all the damage I caused by bumbling about and trying to fix it on my own, although I did have to clean the project to get that bonus.
If you’ve used Eclipse’s “Organize Imports” function to try and solve the problem, you may find that Eclipse tried to import android.R. Effectively, since the compiler was unable to find what you were looking for in your project’s R class, it tries to solve the problem by looking for it in Android’s more general resource class, which not only doesn’t work, it causes other problems: from then on anything you try to use in R will by default reference android.R, where it probably won’t be found. Deleting that import line appears to be good enough to undo the mistake.
It’s Not a Big Deal
Ultimately, running into this problem was probably my fault for trying to rename a package, which in hindsight seems like it’s probably not a great idea to begin with. I’ve always had a tenuous grasp on why the name of a Java package matters anyway, but it seems like the lesson to be learned is to pick one and stick with it.
Oddly, this issue really only seemed to affect files in /res/raw; when trying to debug the issue, referencing files in /raw/layout did not appear to throw additional errors. This is probably indicative of unintended behavior, but it’s easy enough to avoid and correct that it’s probably not worth Google spending development time to fix it.