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)
Related
If I have different resource names like elephant, tiger and cat. And I want to create a method accepting the resource name and return the drawable object. Then I wrote this
public Drawable getDrawable(String name){
int defaultResId= ResourceOptimizer.getResId(name,R.drawable.class);
return getResources().getDrawable(defaultResId);
}
which the ResourceOptimizer is
public class ResourceOptimizer {
public static int getResId(String resName, Class<?> c) {
try {
Field idField = c.getDeclaredField(resName);
return idField.getInt(idField);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
}
But the problem is that getResources() needs to be called
in an activity or fragment, otherwise you to pass the context.
Passing the context might cause memory leak. Especially, when
it has to be passed through several classes. I’m wondering if
there is some way to get the resource by a better convenient way.
like
R.id.DRAWABLE_NAME
which the ResourceOptimizer is
Resources already has a getIdentifier() method.
But the problem is that getResources() needs to be called in an activity or fragment, otherwise you to pass the context.
Correct. Resources are only available by means of a suitable Context. Note that "suitable" depends on circumstances; for UIs, you almost always want to use the Context from your activity or fragment. For example, you might want different drawables based on whether the device is in dark mode or not on Android 10+.
Passing the context might cause memory leak
Not with the code that you have here, as you are not saving the Context, or anything from it, in a field that might outlive the Context itself.
I’m wondering if there is some way to get the resource by a better convenient way. like R.id.DRAWABLE_NAME
getDrawable() is a method on Context. So, call getDrawable(R.drawable.elephant).
Your code is trying specifically to avoid using R.drawable, instead using the String name. So, this turns into:
getDrawable(getResources().getIdentifier(yourString, "drawable", getPackageName()))
where yourString is the string basename of your resource (e.g., "elephant").
Ideally, you would cache the value returned by getIdentifier(), if you expect to retrieve the same resource by this code many times within the life of your process. Reflection is not cheap.
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.
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 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()
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)