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.
Related
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 building an application and use labels in the following areas.
1. Component Names (TextView, Buttons etc)
2. Buttons in alert boxes
3. Parameters to AsyncTask
4. Key names in Intent extras
5. Log tags
I have got strings.xml files to store and use labels. I am using using it for category 1. What do you think is the best option for others?
res/strings.xml or
Constants class ?
I'll suggest to you what I normally do:
For everything that the user will read on the screen or be referenced in anyway from a XML layout, use strings.xml. I reckon that includes your 1 and 2. But remember that for AlertDialogues you can also use android.R.string.ok or android.R.string.cancel, etc; that will vary from use to use.
Also for project config values, or API keys, you could have a config.xml with String, Integers, etc. Something that makes easy to later on change those values without diving into the code.
For AsyncTask, it varies a lot of what work it is doing, but usually a network, DB or disk operation, and I try to include private static final String URL_PT1 = "http://..."; etc, in the classes themselves, as they are the only interested in knowing that address (or DB columns, or file prefix)
For key names (both in Intent and Fragment arguments) I use private static final String KEY_VALUE = "renjith.Key.MyClassName.VALUE"; and then create a public static Bundle getIntentExtras(String value) inside that class that will properly allocate the value in the extra. That's because only that one class needs to know about it's KEY values, there's no reason to make those public accessible, that will just create errors for outside classes doing it wrong.
For Logs (5), create on every class a private static final String TAG = "Renjith.ThisClassName"; (and for Fragments make the TAG public to be used in transactions). That way you can create a filter in LogCat Renjith.* and you can easily identify from where this log is coming from
edit:
For sharedpreferences it depends:
for GlobalSharedPreferences I would create one class to handle them with static set/get methods that must receive Context and all keys private static inside that class.
For local shared preferences (that only one class is interested in saving/retrieving) I would handle in a SharedPreferences file with the same name as that class and all the keys as private static inside that one class.
Again, same philosophy, only the classes that really need to know about those details will know about them, and abstracting to the rest of the classes with direct method calls.
I need a solution for the really common but important issue that i am thinking of.
I have created application in which i have hard coded my server address in /res/values/strings.xml file. Suppose if my server address changes run-time due to some reasons, then i have to make changes in the file and then i have to recompile it.
So is there any way that i put my server address out of my application.. So we do not have to recomplie the application. Instead of it, it will read new server address from out side and resume its normal work...
Any type of related suggestions,links,blogs appreciated..
While I am making apps in Android , I mostly create a Utility class e.g. Constants.java , Utils.java etc. In these classes, I put all the constant numerical and String values like this:
public static String ip="74.117.153.111";
public static final String LOGIN_TOKEN_URL = "http://"+ ip + "/api/getLoginToken";
public static final String USERNAME_PARAM = "username";
public static final String PASSWORD_FIELD_EMPTY_ERROR = "Please enter password";
public static final int GRID_ICON_COUNT = 4;
public static final String FACEBOOK_KEY = "16411636362877862";
These are some type of constants which we generally use here and there. So I put them into a different dedicated class. So now when I need their value somewhere, I get it like this:
params.put(Constants.USERNAME_PARAM, username);
fbRocket = new FBRocket(this, Constants.APP_NAME,Constants.FACEBOOK_KEY);
The benefit of this approach is that if I have to change a value later on which is being used at lot of places , then I don't have to change it everywhere. I will just change the value in Constants.java and this change will replicate in the whole app.
Utils.showErrorMessage(this, Constants.PASSWORD_FIELD_EMPTY_ERROR, Constants.TOAST_VISIBLE_SHORT);
I got the answer by reading this blog.
Which says you should use shard preferences with the activity extending PreferenceActivity.
Here you can set your server address and all the dynamic stuff that will change by the time. So that you will not have to recompile the apk. Just change the settings in shared preferences.
Read this important bog that all app developer wants to know it..
I want to use a particular string found in the Values folder into normal classes. This is for my localization process with different languages.
How would I do this?
Use the getString() method on a Context (such as an Activity), specifying the key in this form: R.string.you_key
If you need to get a String outside of an Activity, like in a helper class or something, just make sure you pass in a reference to a context.
Access the value by calling getString(R.string.your_string);
Ex.
String myValue = getString(R.string.your_string);
obviously replace "your_string" with the actual name you gave the string
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.