I have a String is like String data="apps";
i know loading String in Android in two ways..
First one is
so it is a constant i defined it as
public static final String data="apps";
And another type is defing it in res/vslues/strings.xml file like..
<string name="data">apps</string>
<string name="hello_world">Hello world!</string>
if i want to use it..
for the first way ClassName.data
for second way context.getResources().getString(resourceid)
Question:
so now my question is I want to use same String in 30 times in different classes.And I have more number of variables.so which will load faster and take lesser memory in the above methods..
However, speed shouldn't really be an issue in either case. I would recommend organizing based on what makes sense.
Constants class
Put strings constants that will be used internally, like database column names or other keys.
strings.xml
Put strings that are displayed for the user. This way you can take advantage of localization, etc.
As per requirement you should be prefer second approach means XML
based.
The XML string values are meant to be display strings that can be overridden based on locale. This way you can refer to a translatable display value by a constant key.
You should consider using XML strings as a way to display something to the user and change it depending on locale.
Never the less, public static final String data="apps"; should be used in order to hide some not-for-user data like db connections, log messages etc.
I'd suggest that you leverage the Android resource system.
To quote the book Android In Practice:
Resources in Android are efficient and fast. XML resources are compiled into a binary format. This makes them friendly at development time, without being slow at Runtime.
I think the speed and memory usage would be the same. The constant in a class is just like a constant in the string.xml which is stored once and referenced whenever you need it elsewhere.
However, the advantage of storing in string.xml over the other would be the extra import lines of code which would be avoided. Meanwhile, you have to remember that with string.xml storage you can only use it where the context of an activity is accessible.
Related
I have heard that using editor.putString("Message","Hello"); is bad practice, and you should instead do editor.putString(getString(R.string.messagestring),"Hello");. But why? It is longer and has the same result, and looks more messy imo. Is it because it's harder to make a typo?
Here is an example from Signal:
Source
if (params[0] < SCREENSHOTS) {
boolean screenSecurity = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(TextSecurePreferences.SCREEN_SECURITY_PREF, true);
TextSecurePreferences.setScreenSecurityEnabled(getApplicationContext(), screenSecurity);
}
String values in code for human readable text are bad.
Doing so makes localization impossible.
Values from R.string. on the other hand automagically use the right language (given that you use values, values-es, values-fr, ... and put translations)
Note: You should probably not translate the key of a SharedPreference but the value ("Hello") part since that's presumably the human readable thing.
editor.putString("message", getString(R.string.messagestring));
The key could change if the user changes device language which means the old stored value will no longer be found under the new key. If you want keys in a central place it's a good idea to have them defined as static final constants in code.
editor.putString(MyPrefConstants.PREF_MESSAGE, getString(R.string.messagestring));
I would actually consider using keys that come from R.string a very questionable design decision. This applies to anything that is intended to be machine-consumed rather than visible text to the user. There are a few exceptions but they are rare.
It's Not Necessary but Good Practice.
eg.
editor.putString("Message","Hello");
here the key -> "Message"
it is possible that sometimes you make a TYPING ERROR or SPELLING MISTAKE of writing "Message" to "Massage" or something else.
to avoid these type of situations, we should write in this way
editor.putString(getString(R.string.messagestring),"Hello");
It's all about maintenance, reusability, cleanness and if needed easier localization. Take for example "Message".
How many times would you use this string in your code if it is the key for Preferences? More than 1, right? Imagine that you write over and over "Message". Isn't it possible to misspell it at least once? Well you can't misspell a string resource, because the compiler won't let you.
Another thing: you know where all your UI strings are so you know where to look when you need to change 1 of them and once you do it is changed throughout the app.
Finally if you want your up to be multilingual this is the only way with the Editor provided by AS.
Edit: As for the question if strings like keys for Preferences should be in the Resources my answer is yes. It's up to the programmer to give proper ids to the string resources so to distinguish the UI items from the in-app items.
I'm wondering what the drawbacks are for using strings that are defined in the java files in Android code.
I like to use plain old Java strings for things that are not visible strings like e.g. names in XML documents that I'm parsing, or keys for bundles. Seems to be a good idea to just keep all those things in the java file where they are used instead of moving them out into an XML file and making the code more complicated.
Yet, I see many examples of Android code that seem to put every string into a resource file.
What's the issue with having strings in java files? What are the reasons that people don't do it? I've been doing it in my apps and haven't seen any issues yet so far.
Note that I'm aware that XML files make a ton of sense for stuff that needs to be translated. This question is for cases where the strings stay the same.
Let me try to make this question clearer:
Are there any reasons except:
Because it's a standard / best practise etc. - my question is basically: why is it a best practise, only because of i8n, or are there other reasons?
Because it allows you to use the resources framework for translation, device-dependent strings etc.
Because it allows you to use non-ASCII characters.
The simple answer to your question is its a standard to put all your string into resource. Also there are many reason that if you are keeping your string in xml/java file you have to update each and every reference in these file for a single string.
for eg. if You want to change "Ok" to "confirm" which are used in 5 different file you have to change in all those 5 files but for String resource you just have to update one file which string.xml.
Edit
Please find below some of reasons we should use String.xml
1) To update single reference to multiple occurrences. As according to the #treesAreEverywhere It can be done with public static String, but it will take memory on startup of application and till application is closed. But String written in String.xml will be loaded at time of use.
2) Multiple language support. You can create multiple language resource folder to support your multiple language application so language changed using Locale will be dynamically maintained by OS at run time according to language resource folder.
3) Please check Localization document which provide you more information about using string.xml
4) Strings don’t clutter up your application code, leaving it clear and easy to maintain.
It's a kind of coding standard like any other language has. But you can ignore it if you want and can create your code with public static string variable in code. It is not compulsory to use string.xml but its a good coding practice to use it. Good practice like closing the if block with parenthesis containing single statement rather than leaving it as it is.
if(condition){ statement; } rather than if(condition) statement;
Actually, good practices is a good reason to do it, but there are more.
For example, one reason that I can recall right now is that strings.xml is UTF-8 codified. Hardcoded strings doesn't show some characters properly.
The purpose of strings.xml (and other *.xml resource files) is to regroup similar values in one place. This facilitates finding values that would be otherwise buried in the code. Those resource files also makes the maintainability better, since a modification to one value can have app-wide effects (such as changing the title of the app or the theme). Finally, as you mentioned, it provides a framework for translating your app to other languages.
If you know your app will not be translated and won't be modified, it's not a bad thing to hard-code them. However, if you think your app will get a lot of updates, it is better to start using good foundations and use XML resource files.
Besides these reasons and the ones mentioned by #Zinc (which I am unaware of and cannot confirm), there are no other reasons regarding why you would want to use XML resource files.
The drawback of using resource files is that is is theoretically is slower and requires a bit more memory. Read android - strings.xml vs static constants and Does hard coding of string affect performance?
If you put all your strings which are related to your application, then you can implement I18N kind of applications very easily and it is very useful while doing application changes (Company takeover some other company). It is just change names in xml files. No need to touch any java file.
How do I avoid (some) of my string resources getting localized?
Sometimes I need the same string multiple places. For instance when defining a preference I need the preference key both in my preferences.xml and in my java code in order to get the preference value. Either I can manually define the key twice (which I do now) but I feel that my list of keys is getting large and error prone.
I could also define the key in my strins.xml but then I fear it will get translated (sooner or later (by mistake?)). I fear this could cause problems to have the same preference value store multiple times with different keys. What if the user changes language and all the settings got reset?
Is there a way to define a string - accessible both in code and xml - which will not get translated as a part of the localization process?
In general, if you provide the string only in your default strings.xml it will appear the same on all locales. In addition you can use the "translatable" attribute which will tell Lint that this string is not designed to be translated, and will serve for documentation purposes.
Just use translatable=false. And I suggest putting your preferences keys to separate resource file as it would be easier to manage.
<string name="Key" translatable="false">my key</string>
I've taken a look at the following post to grasp a basic idea of how to deal with I18N:
Where to place i18n key strings in Java
But more than that, I have an intention of automatically generating a Java class with constants storing key strings of I18n property files. I know it could be feasibly done using Java itself, however, I wonder which is the best approach (using Ant, Batch or something else...)?
The best approach is to give the identifiers yourself.
The ID can give hint to the translator what the string is about.
In fact, some consistency in naming convention is best:
dialog.print.title = Print
menu.file.print = Print
The two entries have to be translated differently in some languages (for instance in French it would be "Imprimer" for a button and "Impression" for a label / title).
Think it it this way: would you like to maintain some code where all variable names are machine generated?
This is a general question about the efficiency of hardcoding data - I'm writing a program in Java that does some chemical analysis, and I need to use the isotopic abundances of different elements. The way I have it set up right now is that all values (which never need to be modified) are stored as final fields in my class, i.e.
static final double C12Abundance = .989;
static final double C12Mass = 12;
A lot of similar programs store this type of data in an XML file, then read the values from there, like this:
<compounds>
<elements>
<element symbol='C' mono_isotopic_mass ='12.00000000000' abundance='.989'/>
Is there any reason (performance, memory, etc) to read from it this way? Seems easier to just leave it as a field.
Hard coding is way much faster in terms of performance and memory allocation.
The thing you gain from reading from a file is code re-usability (running your program with different parameters without the need to recompile it).
Note that reading from a file has the following steps:
Declare variable to use for storing a value.
Create an input (stream) object
Initialize it with a path
Open The file from FS
Find the correct line to read from
Read the value
Store it in the variable above
Close the input (stream)
That's a pretty big overhead instead of having a pre-compiled final variable with a value
As these are truely universal constants, properties limited in number, you can put them in code, but nicely organized.
public enum Element {
// Name Mass Abund
C12("C", 12.0, .989),
He4(...),
O32(...),
...;
public final String name;
public final double monoIsotopicMass;
public final double abundancy;
private Element(String name, double monoIsotopicMass, double abundancy) {
this.name = name;
this.monoIsotopicMass = monoIsotopicMass;
this.abundancy = abundancy;
}
}
for (Element elem : Element.values()) {
if (elem.abundancy > 0.5) {
...
}
}
If you want to hard-code the values and want to change them, you have to recompile your program, that's the problem. Reading your data from a file have the following benefits:
You don't have to wait for the program to recompile for every change in the data. For a fairly large program, this can take time.
Your users can change the data without even having access to the source.
You can have different data sets between which you can switch just by changing the config file name.
Maybe none of this matter to you; then just go ahead and put your data in the source.
Performance itself (as in the performance of the program) is never a problem except if your profiler says so. But I don't see how reading for the data file at startup a small set of data could be a long process, so I'm fairly sure you would'nt see a difference.
If you want so simulate a universe with a different abundance of C12, having the values hard coded would mean you have to recompile the program.
There may be other reasons as well: if the values are read from an external file the file serves as documentation, an external file may be easier to check for errors, there may be tools that generate the file or use it for other purposes besides running your program, ...
A configuration file holds properties, generally speaking these properties are changing in time. I believe that in your case those are fixed and will never change, by definition.
For this reason I would do the easier thing possible, which is leaving them as fields.
This is not a performance matter, as long as performance doesn't show up being an issue, this is just a matter of what is more easily usable in your codebase.
I would advice you to extract these values in a class as constants, so you could always import it to access the values.
The Java code in only readable by a Java compiler whereas XML is readable by any reasonable (meaning XML aware) language. Also If you want to add some value, you don't have to recompile everything.
Personally I'd go for hardcoding if the values are not gonna be changed ever and if the app is small. Otherwise I would choose external sources of conf data.
But everytime people tell me that values are not gonna change, it pretty much means that they will so preparing dynamic environments is the way to go in general. XML conf files, database conf tables etc.
If you write them in XML you can use different values for different devices,
e.g assume you have a dimension with name item_margin and it needs to be different based on width of device so in values/dimens.xml you have this
<dimen name="item_margin">0dp</dimen>
and in devices which has min 600dp width you want this margin to be 60dp so in
values-sw600dp/dimens.xml you have this
<dimen name="item_margin">60dp</dimen>
in this way these values are automatically selected based on device width, thus you don't have to check the device width and select appropriate value in your Java code