Concept behind the Java resources, striking gs, "R.id" - java

I ran into an issue that made me realize there is core concept I'm not getting.
For some reason when I went to add a value to my strings.xml file, something happened and my xml file was giving a parsing error. The only way I was able to fix this was by deleting the strings file and re-creating it by right clicking on the values folder, and going to "add android xml file" and naming it strings.xml.
This made the error go away, but now, my activities are complaining and saying they can't resolve R (as in R.id).
This made curious as to what's the relationship between R and the xml files. And why is that when you reference a string, you use #String/something, when the file that contains it is called strings?
Finally why is it that even though I created an xml file called strings.xml, in the right location, my project doesn't see his as the THE strings.xml file?

Names
The R resources are organized in a specific manner:
R.layout.* - These resources are your layout files, which you have created in the various layout-* folders
R.menu.* - These are the resources which are your menu files, created in your various menu-* folders.
R.id.* - These are the resource identifiers for your various Views and Menu items etc. There can be more than one element with the same ID, as long as they're in separate files.
R.string.* - These are your string resources, declared in <string> elements in files in your values-* folders. The filename is irrelevant. There can only be one string element with a particular name in a single folder. So you cannot have two hello strings in values, but you can have one each in values and values-en.
R.drawable.* - These are the various XML and image drawables you have in your drawable-* folders.
There are many more, but these are the most common. I'll add the rest when I have a bit more time on my hands.
After compilation
During compilation, the Android build system puts all XML files into a binary format. Everything except the /res/raw is compressed as well. This is particularly helpful with layouts, which can be inflated faster after compression. Individual files cease to exist after compilation, and everything becomes one big binary file. You access the data in this file using R.<resource_type>.<name> from Java, and #<resource_type>/<name> from XML
Naming
For some resources (drawables, layouts, menus) the filename matters, as the resource is referred to using that. For other resources (strings, colors, styles), the filename is irrelevant, as long as you use the correct element (for example <string> for Strings) when declaring them within the file.

When your project gets compiled and built, one of the things that happens is the generation of the R file. Each named resource is given a public static final int identifier, like R.string.foo, which would reference a string defined with name="foo". This way you can reference a resource from Java and Android will map it to a resource and load it from your application package.
Resources can be overloaded; you could have two strings both named foo that are qualified for different configurations, but they have the same identifier in the R class. The system will choose the one that best matches the device configuration at run time.
If there is an error with any of your resource declarations, R will fail to build and any java classes that reference it will therefore complain about it. You can do Project > Clean in Eclipse and see if that helps, but otherwise make sure your resources are properly declared and/or have valid names.

R.java is a seperate file created by eclipse,
its not related to strings.xml ,Clean your project then build and run again .
you will found R.java inside your gen folder
Read this
http://developer.android.com/tools/projects/index.html

Related

Cleaning messed up my Android project

I changed some images in drawable-xxhdpi folder from jpg to png (by deleting jpg and copying png). When I started Eclipse, the error reported was:
res\drawable-xxhdpi-v4\stripes.png:0: error: Resource entry stripes is
already defined. res\drawable-xxhdpi-v4\stripes.jpg:0: Originally
defined here.
So I look that up and it says I should do Project>Clean, so I do, and now all .java files are are reporting errors on every line where R.something is used, for example:
setContentView(R.layout.activity_about);
reports error R cannot be resolved to a variable.
Then I looked this up and the problem is said to be xml errors, but:
I didn't touch any of the xml files, I just changed jpgs to pngs
none or the xml files have errors reported anywhere
You can't have two resources of the same type with the same base name. You have these two right now:
res\drawable-xxhdpi-v4\stripes.png
res\drawable-xxhdpi-v4\stripes.jpg
They have the same base name "stripes" but with different extensions.
When the Android tools build your app, the name of the resource in your R class only contains the base name of your resource, but it will complain if two resources have the same base name.
You just need to give one of them a different base name so they can have two different resources defined.

Accessing folder in android

I am working on an android app in which I need to detect the language of user's input text.
So using Stackoverflow I found a recommendation of using a java library called langdetect which requires reading languages profiles.
I was able to create a simple plane java project, by adding a directory (folder) inside the java project called "profiles" which contains all the languages profiles.
I couldn't make this work in android since the only 2 ways I know of accessing files in android either by adding the desired files inside "assets" or "rec/raw" but I keep getting error saying file not found.
The method from langdetect jar file that requires reading profiles is the following
String path = "profiles";
DetectorFactory.loadProfile(path);
the above code works in plain java.
Any help guys.
I used the following
Uri.parse("android.resource://com.my.package.my.app/raw");
file:///android_asset
classLoader.getResource("profiles");
and many others in the same style.
The problem is that I don't need to access specific file per say, the only thing I need is a path to the folder that contains the languages profiles, the folder contains 53 files for 53 languages.
path is relative. It does not make sense in Android. You should refere the Internal/External storage with Absolute Path. If you put your data inside the sdcard, for instance, you can retrieve the Absolute Path with Environment.getExternalStorageDirectory(). If you want to embeded your data inside the apk, using the assets or raw folder, you need the AssetsManager in the former case, getResources() in the latter.

A static resource file?

Android uses a static resource file R. This file (at least in eclipse) is automatically updated when ever you add new id's of any sort. How can I create/implement the same feature in a normal java application? Is it as simple as just writing an xml parser and just updating the resource file after the xml is modified?
In a way, yes. You need to create a custom build script/program which runs at the start of each build (before anything else), scans your resource folder files (and if they are XML files it needs to read in the XML files and parse out the string resources or whatever from those), then write it all to a Java file in some manner (e.g. R.string_name = "string value").
Make sure the XML files aren't actually packaged in your .jar, since all that information will be stored inside your Java resources file now.
For things which aren't XML files you could just store the filename as a string in the Java resources file.
You didn't specified the type or the use of the resources. I don't know android, but I'll try to help; If you just need to access some resource in your application you can use properties or resource, there are some differences see this other question Properties vs Resource Bundle

Does Java getResource method only work with particular extensions?

The following piece of code works fine
getClass().getResource("/index.xml");
However when I do a full refactor to
getClass().getResource("/index.html");
The above line throws NullPointerException. I know I have refactored correctly because I rename the file using IDE smart refactor i.e. the file index.html definitely exists in the same directory. As soon as I switch back to
getClass().getResource("/index.xml");
Everything is fine again. Is there any reason why only the .xml extension works?
As #a_horse_with_no_name mentions, using getResourceAsStream( ) should work fine with any file and any extension.
I'd be inclined to believe (based on the information presented) that your IDE hasn't properly refreshed its file hierarchy after the refactor. I'd suggest running a full clean and build of your project, see if that helps the situation.
So, most of the other answers, the class/class loader shouldn't be looking at file extension You could write a ClassLoader which did that, but it would be odd.
I'm going to take a stab at what your problem is. I am guessing using some IDE (you don't specify which) that is copying certain files from your source folder into the destination (either a jar or a directory of classes and resources). For Java code, you want the compiled .class object files there and not the .java sources. So the IDE will be configured, with some reasonable default [magic], to copy files with only certain extensions. HTML files were used for old package JavaDocs (package-info.html rather than package-info.java which can include package-wide annotations), so are arguably reasonable to exclude by default.
Therefore, you should investigate what the project is doing in this area, and change any configurations accordingly.
Using getResourceAsStream() should work with any file extension (at least it does for me)
Recognised Java Resources are either a class extending ResourceBundle or .property file.
You can write your own extenstions to enable Resource to be gathered from other extensions.
I'm unsure why .xml files are a viable extension. Are you using Java 7?
From the JavaDoc guide:
The name of a resource is independent of the Java implementation; in
particular, the path separator is always a slash (/). However, the
Java implementation controls the details of how the contents of the
resource are mapped into a file, database, or other object containing
the actual resource.
A resource is identified by a string consisting of a sequence of
substrings, delimited by slashes (/), followed by a resource name.
Each substring must be a valid Java identifier. The resource name is
of the form shortName or shortName.extension. Both shortName and
extension must be Java identifiers.
And read this doc which tell us : an absolute resource name is constructed from the given resource name using this algorithm.
getResource() will work regardless of the type of resource. All it does it return a URL. This example works fine for me.
public class Example {
public static void main(String... args) {
System.out.println(Example.class.getResource("jaxb.properties"));
System.out.println(Example.class.getResource("test.xml"));
System.out.println(Example.class.getResource("foo.html"));
System.out.println(Example.class.getResource("danger.exe"));
}
}

R cannot be resolved to a variable [duplicate]

This question already has answers here:
"R cannot be resolved to a variable"? [duplicate]
(30 answers)
Closed 2 years ago.
I got all of this code from here
I am extremely new to all of this, and am having a few problems.
The error "R cannot be resolved to a variable" comes up on the bold parts of this code.
Resources r = context.getResources();
**setBackgroundColor(r.getColor(R.color.candidate_background));
mColorNormal = r.getColor(R.color.candidate_normal);
mColorRecommended = r.getColor(R.color.candidate_recommended);
mColorOther = r.getColor(R.color.candidate_other);
mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding);**
mPaint = new Paint();
mPaint.setColor(mColorNormal);
mPaint.setAntiAlias(true);
**mPaint.setTextSize(r.getDimensionPixelSize(R.dimen.candidate_font_height));**
mPaint.setStrokeWidth(0);
The only thing I can think of is that I haven't copied and pasted everything correctly?
R is a Java class file that basically maintains an index of resources by assigning every resource that your application uses with an integer value for lookup. If you look in the res directory of the sample you're following, you'll see a values directory underneath it containing a colors.xml file that defines any custom colors. Note that in this specific example, you are using a color resource, not a Color State List resource as Paul had mentioned. Color state resources go in the color directory, but definitions of simple colors go in the values directory. Confusing, I know.
Resources in Android are defined via XML files. R.java is created automatically by the Android build process when these XML files are parsed. Different types of resources need to be placed in to specific directories for R to be structured properly; quite unhelpfully, not all of these directories are automatically created for you when you make a new project under an IDE.
Read this article about Application Resources, this article about providing resources, and this article about accessing resources (all Google documentation) for a bit of a better understanding.
Lastly, if you DO have all of your XML files in the proper place, check your import statements. Sometimes conflicts can arise if you have too many imports or if all of your imports aren't in place; if you're using the official Android Dev Tools in the form of the Eclipse plugin, the easiest way to handle imports is to use the Ctrl+Shift+O shortcut (Cmd+Shift+O on a Mac). If your imports are correct, and all of your XML files are in place, perform a rebuild on the project. If this still doesn't work and you are using Eclipse, I know that sometimes Resource resolution conflicts can inexplicably be fixed by simply closing Eclipse and launching it again.
R is an automatically generated file made from your resources.
Taken from Android docs
Color State List Resource
Define a color resources that changes
based on the View state. Saved
in res/color/ and accessed from the R.color class.
I would guess that the different R.color.candidate_* all need to be defined under res/color/
The R.java file should be automatically generated by Android. Try the following:
If you are using Eclipse try "project clean" to regenerate the file.
Use Ctrl-Shift-O to "reorganize" your imports. This will automatically add the R.java file to your imports if necessary.
Try to fix all errors not related to the R file and then retry the "project clean" and Ctrl-Shift-O option again. Other errors (e.g. typos in your xml layout files) can "stall" a new build of the R file via project clean.
Make sure your project is an Android project and you have an android.jar file on your classpath. If not fix this and retry step 1-3
you ned to copy the resources om the example you are using into the releavent directories in you res folder. The first word (after R.) is the directory you use.
so for R.color you put the resoruce in res/color in your project.
for the xample the resources are here:
http://developer.android.com/resources/samples/SoftKeyboard/res/index.html
they should also be in the version of the android SDK you downloaded:
ADKPATH/samples/android-/SoftKeyboard/
I got this error message many times. And mostly all of them were caused by some mistake in xml files or that I forgot to put 'check' in front of Build Automatically option. Try it! Maybe it will help You.

Categories