when passing extras such as Intent.putExtra("myName", myName), what's the convention for the name of the extra?
ie: if passing data between two activities, both would put/extract data under the id "myName", but should I just hardcode "myName" everywhere, or keep the value in the R.values.string?
Hardcoding is definitely not an ideal solution.
The convention used in the Android framework is to create public static final constants named EXTRA_FOO (where FOO is the name of your key) like Intent.EXTRA_ALARM_COUNT
The actual value of the constant is a name spaced string to avoid conflicts: "android.intent.extra.ALARM_COUNT"
If you don't want to create dependencies between your Activities with constants, then you should consider putting these keys into string values within your strings.xml file. I tend to follow the same naming convention when defining the keys in xml:
<string name="EXTRA_MY_NAME">com.me.extra.MY_NAME</string>
It still reads like a static constant from the Java side:
getString(R.string.EXTRA_MY_NAME);
The only thing I saw in documentation is that extra keys should start from package name. However I do not fully follow this and the app works Ok so far.
I would prefer to use R.string.some_key within the code just to have it clean and dry.
Related
I can store them in res/strings
<resources>
<string name="str1">app</string>
</resources>
And I can store them in static const
public static final string str1 = "app"
Which one is better?
I mean that which one will use more memory and which one will make package larger.
If you have to change some text in your app's view, then you don't have to find where you have written that text. You simply go to the strings.xml in res folder and can change the string. For that reason, the first option will always be the better option.
If you want a string that will be used as a key in your app then you can store it in a static constant variable. Like: If you want to pass data through intent or in any other way, at that time you have to pass a key. That key will be a string and can be stored in a static constant variable.
it's really depend if you treat strings as constants or not.
If you string are constants (e.g. string that will be sent as key of intent) then you can either create some Constants class or define it as a constant in your activity/fragment class. If those string are texts that will be displayed on your application UI then they should be defined as resources in your application.
BTW all the resources string can be localized to different languages
If you need more info or examples please let me know.
The package size:
I believe that "Ran Hassid"'s comment describes well about the package size.
Memory usage:
Just create an android apk file with some static final strings and then decompile it. You will see that the variable has no initial value in the compiled version and the value is replaced in all references!
For example check this sample from my decompiled apk which is also obfusicated by proguard:
public static String f10850f;
...
...
...
hashMap.put(C1554f.m14687a("\u0014]SCVQ^V"), str);
here is the actual code I have written:
public static String packageName="\u0014]SCVQ^V";
...
...
...
hashMap.put(EncryptorClass.decrypt(packageName), str);
In this case, the static final String variable in my written code has value of "\u0014]SCVQ^V" but it is not used in run-time and just copy/pasted in related pieces of code.
So using static final String variables needs no memory because variable has no initial value.
Have a look at android docs about using static final variables
Also take a look at this post regarding memory of variables with no value
Overally, I use static final variables and string resources for different purposes like code encryption, language support and whether I want to access the variable using a Context or not.
I am wondering if you should use strings.xml instead of global constants. I learned that global variables should be avoided but then again strings.xml are probably not ment to be used like this?
Are there any advantages / disadvantages using one or the other?
I am pretty sure that hardcoded strings like the following is not a good way.
putExtra("extraKey", extra);
With strings.xml or Constants you have a spellcheck and autocompletion.
A typical line with R.string could look like this.
intent.putExtra(getString(R.string.first_player_for_intent), firstPlayer);
in comparison to the
intent.putExtra(MyClass.first_player_for_intent), firstPlayer);
If you should use constants, in what class should they be located?
I wouldn't use res/strings.xml to store constants. You might want to access their value even though you don't have a context. Also, your keys don't need to be localized. Regarding the place where you should store it, it is up to you, and imo, it is just a matter of taste. I usually avoid having a dedicated class just for constants, but I declare it where it imo belongs. For instance, if you have a class called Player, I would put all the constants Player related there.
strings.xml is there for a purpose and primary purpose of it is to support localization.
you should not be overloading this system with constants which are not relevant for localization.
As Blackbelt correctly said you may need to access your constants even without context so that's another reason.
I have a lot of Intent to send message between activities and services in my APP.
Usually they will have some Object to pass by bundle.putString(key, someObject) and bundle.getString(key, someObject).
I want these keys to be well organized so I will be clear with messages being sent.As I think, they should be constants in Java, but for android, would it be better to put them in res/values/strings.xml named as key_xxx_xxx.
Thanks for any answers or comments.
Well, I thought about this matter a few days ago.
Use Java is better than strings.xml, like Android' s permissions are all Java public static final field. If you hava a lot of constants, you can also prepend a package name to be clear and identical, which strings.xml cannot supply.
If your xml file use the the key, I think is better to put the key in the strings.xml. For example, your settings xml file need a string key, and your java code also needs it, if you just put that key in java, you need to set text literal to the settings xml file, that may not good...
in short, it depends on the key used in java or xml or both.
hope it helpful!
It would be good to keep them as static constants. Make a java file as Utils.java and keep all the names there as Static Constants.
Something like this:
public static final String FIRST_KEY = "my_first_key";
I am doing some debugging in my application, mainly loading custom styles from styles.xml when my custom view is given a style="#styles/CustomStyle", and attributes such as custom:attribute="custom value"
I looked into the TextView source to see how Android loads styles/attributes and I am mimicking that. However I am not being passed any of my R.styleables through some of the calls to my constructors and so I am trying to peek in there to see which resources are coming in.
I am using obtainStyledAttributes() to load these key/value pairs into a TypedArray, however I am wondering if there is an easy way to convert the R.styleable.CustomWidget_customAttribute from the int that R reads, to its referenced name.
In essence, I want LogCat to say, "We've been given R.styleable.xxx" and not "We've been given 1487214712442"
Look at this method: http://developer.android.com/reference/android/content/res/Resources.html#getResourceName(int)
Return the full name for a given resource identifier. This name is a single string of the form "package:type/entry".
You most likely are not able to do this explicitly, as all resources are stored in a generated java class with no accessible reference to the original strings.
However, your best bet is override the toString() method for the R class.
See if something like that works.
Hope this helped!
i found this problem some time ago, but i solve it using this: getString(), or this: getResources().getString()
but now, for this case, it doesn't works, i think it's because i need to get the string values on a NON ANDROID ACTIVITY CLASS. I need the resource values on a remote connection class, that doesn't extends any kind of activity or service.
how i can acces to the variables from my strings.xml on this normal class?
this is the code where i get the error (it gets an integer, and not the string value)
String a =R.string.totalpermission;
Take a look at these two answers (are the same XD):
How to obtain AssetManager without reference to Context?
How can I get a resource content from a static context?
Just an advice: try to read some basic concepts... it seems you don't understand what the R class is and how to use it. Trust me, you waste less time studying than trying to figure out how things work.
I'll add something to existing answers since I found it very useful.
To get your strings you have to use a Context. Your activity will work just great.
String string = getString(R.string.myString);
But if you have something more complex... for exemple
R.string.result -> "You %1$s %2$d cats"
String result = getString(R.string.result, killed ? "killed": "saved", count);
That would give you a result like that:
You saved 10 cats or You killed 2 cats... and so on. You can pass parameters and positional arguments in strings will get replaced by your arguments in getString.
All Android resources are referenced via a resource ID, like R.string.totalpermission. You can see those numbers in R.java (although there's no reason to ever do that).
In cases of strings, you can easily get those using Context.getString. Bonus: You can even pass optional arguments and add dynamic strings that way. You always have a context - how are you getting called? If you really don't have a context, you can create one for the package your resources are in.