I noticed that the Activity class has two different methods to get a String resource.
This is possible by using:
getString(int resId): Return a localized string from the application's package's default string table.
getResources().getString(int id): Returns the string value associated with a particular resource ID. It will be stripped of any styled text information.
I don't understand what's the difference between both methods. Can somebody tell me?
They are the same as Activity.getString(int) does exactly that:
public final String getString(int resId) {
return getResources().getString(resId);
}
They are the same method, nothing special about them.
In Fragments you can use also getString() instead of getActivity().getString()
Related
I have the following method.
public abstract String getIntent()
And the following class
public class Intents
{
public static final String SUCCEEDED = "SUCCEEDED";
public static final String FAILED = "FAILED";
// hundreds of other strings.
}
I would like to force the return type of the method to be a class variable of the class Intents. How would I do that? I have thought of using some kind of custom annotation like #StringRes
For example:
public abstract #Intents String getIntent()
However if I look at all the available annotations this only seems to work for generated id's in the R.java file. I came to that conclusion because the return type is always an integer and R.java contains multiple classes with similar names like the annotation, with each class containing the generated integers.
So next I was thinking how to create a custom class within the R.java so I could create the annotation. But I didn't find a way to do that. I could just simply create a separate xml and generate an id for every Intent like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="succeeded" type="string">succeeded</item>
<item name="failed" type="string">failed</item>
</resources>
And then use the #StringRes annotation. However this will only limit me to use any kind of string resource.
Another solution I have thought of was to create an enum. In that way I can just simply use that enum as the return type. But I would like to use an annotation if it's possible. Otherwise I would have to rewrite the whole Intents class.
What would be the best way to solve this problem?
maybe something like this?
#StringDef({"AAA", "BBB"})
#Retention(RetentionPolicy.SOURCE)
public #interface Intents {}
public void test(#Intents String input)
{
}
In my current application, I am implementing localization. I came across various ways to access the string (external string). Some methods are:
Accessing directly using R.string.hello
Using getResourse().getString(R.string.hello)
getString.
The Eclipse tool to externalize resources, which creates a message.property file and access the string from a snippet.
The main confusion is between 1 and 2. If I use "1" that is accessing directly, can I get resources based on locale?
TL;DR
It doesn't matter whether you use R.string.hello or getResources().getString(R.string.hello).
Both will point the same thing.
So, yes, for your localization, then it will point to the right stuff.
It's been taken care of.
Some trivial stuff:
R.string.hello is actually an integer.
And most methods, that are used by passing R.string.hello (or other resources) as its argument, basically have the function to translate to corresponding string of the number.
Let's take TextView as an example.
It has two methods for setText.
First:
public final void setText(CharSequence text)
Second:
public final void setText(int resid)
So, when you call using getResources().getString():
myTextView.setText(getResources().getString(R.string.hello);
Then the first method is called.
And when you call using R.string.hello directly, then the second method is called.
If you take a look closer to the source, the second method's content (calling using R.string.hello directly) is actually calling the first method.
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/TextView.java#L4133
Both are provided for our convenience, so that we can use either direct resource R.string.hello or using getResources().getString(R.string.hello).
Implementation of Context method getString():
/**
* Return a localized string from the application's package's
* default string table.
*
* #param resId Resource id for the string
*/
public final String getString(int resId) {
return getResources().getString(resId);
}
So it's the same as using getResourse().getString(R.string.hello) (2), and it returns the result in the proper locale.
I am wondering about the getString().
I can see that doing getString(R.string.some_text) works. Also getResources().getString(R.string.connection_error) works.
So my question is why should we use the getString or when?
Thanks!
The question is easy to misinterpret.
If you are in a valid context (like an Activity), there is no difference, because the context has a reference to the resources, so it can resolve a getString(int); directly, which returns a String.
Adding more information for your peace of mind.
If you can use getString directly, go ahead and do it. Now sometimes you might need to use getResources() because it contains a lot of helper methods.
This is the Android source code for getResources.getString():
/**
* Return the string value associated with a particular resource ID. It
* will be stripped of any styled text information.
* {#more}
*
* #param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
* entry. The value 0 is an invalid identifier.
*
* #throws NotFoundException Throws NotFoundException if the given ID does not exist.
*
* #return String The string data associated with the resource,
* stripped of styled text information.
*/
public String getString(int id) throws NotFoundException {
CharSequence res = getText(id);
if (res != null) {
return res.toString();
}
throw new NotFoundException("String resource ID #0x"
+ Integer.toHexString(id));
}
Neat huh? :)
The truth is that the Resources object does a lot more than just "get strings", you can take a look here.
Now compare with the Activity version of getString():
Return a localized string from the application's package's default
string table.
So in summary, other than the fact that the Resources object will be stripped of any styled text information. and that the Resources object can do a lot more, the end result is the same. The Activity version is a convenient shortcut :)
The methods are same. Logically, there's not a difference. you can assume, it does exactly:
public final String getString(int resId) {
return getResources().getString(resId);
}
The only difference I know is that getResources() may be required to fetch other apps resources as object. getString() will access your own resources.
If you use it for TextView there are two methods setText() in it. One takes (CharSequence string) and another takes (int resId). That's why your both variants work.
Generally I would recommend to define all strings in strings.xml files and get them via getResources().getString(int resId) in the code. Having that approach you'll be able to easily localize your app. You can read more about app resources here
Very Basic difference.
R.string.some_text = return ID integer, identifying string resource in your space
getResources().getString(R.string.connection_error) = Will return you actualy string associated with ID `R.string.connection_error`
They both can be made use in Android system, where many of widgets can take directly id or value of a resource. Practically there is no difference in value returned only difference is is the Term Context, from you activity context is available to you hence calling getString directly routes to resources for this context, while from classes where context is not available say from a Adapter, you will need to first access the Context, then the resource associated with the context and at the end the String so you write getContext().getResources().getString(R.string.connection_error)
I hope it clears your confusion.
One good reason is about formating & styling like :(http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling)
What is the difference between getResources().getString(...) and getString() when called from my activity? I read that getText(...) returns stylized text, but when should I use getResources() as opposed to directly calling getString()?
They are the same nothing special about them if you fetch the Android source code and specially the Context Class for exemple
public final String getString(int resId) {
return getResources().getString(resId);
}
getString() is a convenient way since it is used regularly (you don't need to type getResources()…). Other than that, they're same.
I have trouble understanding the following thing: in my localized application I have an Enum in an activity that stores some localized strings (R.string.aString) which are compared against another localized string.
If while in application I change the locale and I came back and start the Activity that contains the Enum I observe that it's members have are the same as before localization change.
What is the reason for this?
Edit :
class Settings extends Activity
{
public enum SettingPreferenceScreen
{
Connection (R.string.Connection , xml_resource_1)
Legend (R,string.Legend ,xml_resource_2)
.......
String key;
int res;
SettingPreferenceScreen(String key, int res)
{....}
public int getResource (String key)
{
for(SettingPreferenceScreen p : SettingPreferenceScreen.values())
if(key.equals(p.key))
return p.res;
return -1;
}
}
}
First of all, try avoiding Enums when you develop for android.
Second, my guess is that the Enum get created on the onCreate() method
of your Activity and when you open the application for the second time that method is not called. Check the Activity's lifecycle.
R.string does not contain strings, it contains resource ID constants. (Auto-generated int values.) These IDs will be the same regardless of the configuration. The ID constants are used to fetch application resources from a Resources object (or from a Context, which calls through to your Resources). When you call getString or similar, the system will return the localized resource when applicable.
It seems like you're trying to re-implement functionality that Android already provides for you. Can you give us some more details if this is not the case?
Update:
It is not necessary to avoid enums in Android anymore... I don't know when it came but the android sdk now includes proguard which optimizes the code at build time and replaces the enums with int constants (cf. proguard.cfg).
Furthermore, the paragraph telling you not to use enums in the dev guide has been removed (http://developer.android.com/guide/practices/design/performance.html)