21

I would know what is the best practice for storing global constants which can change with the environnement (debug, preprod, prod, release, etc) at compile time.

In iOS, I used to keep all global constants in a header file and change it with pre-processor macro see this answer:

Where to store global constants in an iOS application?

What solution should I use for Android ?

Community
  • 1
  • 1
klefevre
  • 8,595
  • 7
  • 42
  • 71

6 Answers6

28

Create a class constants in your base package folder.

(or create an interface instead of a class so there is no need to reference the class everytime, however this is bad practice due to code readability, but it will work)

Fill it with public static final values.

Moreover, both the class as well as the interface can also be declared as abstract.

Community
  • 1
  • 1
Nickolaus
  • 4,785
  • 4
  • 38
  • 60
  • 1
    Ok, but how can I change it at "compile-time" ? I don't want to store, for example, all values three time (for 3 different environnements) and having to comment all of them only when I want. – klefevre Feb 25 '13 at 12:57
  • with 3 different enviroments you mean projects? Then create a library application, in which you create your constants-class, than you can add it as library, to as many projects as you want. – Nickolaus Feb 25 '13 at 13:00
  • 3
    No, I mean 3 environnements such as debug, preprod or prod for one project. I would like to change, for example, the base URL (just like the answer I quoted in my question) of my webservice API 'http://prepod.xxx.com/ws', 'http://www.xxx.com/ws', 'http://192.168.1.42/ws' with only 1 constant to change such as "DEBUG", "PREPROD", "PROD" – klefevre Feb 25 '13 at 13:07
2

If values for your constants depend on environment (density, locale etc.) then you should use resources for storing them (integer, string, dimen etc.).

In another case you can put your global constants in one file (best practices - use prefixes for every set of constants) or put local constants in related classes (for instance, Intent holds flags. extras, categories and so on).

tundundun
  • 634
  • 1
  • 5
  • 12
  • As I understood your comment above you should use Maven (tool for automated building). You can determine different constants for different configurations and Maven will build different apk's for you (each apk uses one set of constants). See this question for details http://stackoverflow.com/questions/13867148/maven-and-android-slightly-different-builds-for-different-environments – tundundun Feb 25 '13 at 13:38
2

Use public static final values. and keep them in separate java file as follows:

    static String QC    = "http:/************";
    static String DEV   = "http:/************";
    static String CLOUD = "http:/************";


    static String SERVICEURL = CLOUD ; //Use this SERVICEURL in your code at run time
Karan_Rana
  • 2,813
  • 2
  • 26
  • 35
  • This works... but I would never place an URL in a source file. This kind of data must be in a property file, in a config table in a database, command line argument or a system environment variable, for hygiene. – Jose Manuel Gomez Alvarez Nov 10 '18 at 18:27
2

Another solution might be to use the resource file (if you are content with storing only string values).

This could be used to store constants such as the account that this application manages:

Ex. WelcomeActivity.java

AccountManager am = AccountManager.get(WelcomeActivity.this);
Account account = am.getAccountsByType(getResources().getString(R.string.ACCOUNT_TYPE))[0];

Ex. res/values/strings.xml

<resources>
    <string name="ACCOUNT_NAME">com.acme.MyAccountSignature</string>
</resources>

This would also allow you to modify this without the need to recompile (similarly to how you would normally decouple translations, which the strings.xml file is best used for).

  • Can I get these constants without an instance of `Context`? I would like to use some constants in a library that currently do not require a `Context` to work. – 张实唯 Apr 22 '18 at 11:50
  • 1
    Good question, yes you should be able to, see the answer that @Gangnus gave in [this question](https://stackoverflow.com/questions/5574506/accessing-resources-without-a-context) – Tihomir Mateev May 09 '18 at 11:04
2

Pretty simple solutions is here

public class Constants {
    /**
     * Object key prams when pass the json object from server.
     */
    public static final String KEY_EMAIL = "email";
    public static final String KEY_PASSWORD = "password";
    public static final String KEY_DEVICE_TOKEN = "device_token";
    public static final String KEY_DEVICE_TYPE = "device_type";
    public static final String KEY_NAME = "name";
    public static final String KEY_COUNTRY_CODE = "country_code";
    public static final String KEY_PHONE_CODE = "phone-code";
    public static final String KEY_GENDER = "gender";
    public static final String KEY_DATE_OF_BIRTH = "date_of_birth";
    public static final String KEY_USER_ID = "user_id";
    public static final String KEY_LIMIT = "limit";
    public static final String KEY_DRIVER_ID = "driver_id";
    public static final String KEY_LONGTITUDE = "logitude";
    public static final String KEY_LATTITUDE = "lattitude";
    public static final String KEY_RATING = "rating";
    public static final String KEY_DETAILS = "details";
    public static final String KEY_ACCESS_TOKEN= "access_token";
    /**
     * Fragments name
     */
    public static final String FRAG_ETA = "ETA";
    public static final String FRAG_ACCOUNT_FRAGMENT = "ACCOUNT_FRAGMENT";
    public static final String FRAG_SETTING_FRAGMENT = "SETTING_FRAGMENT";
    public static final String FRAG_MAP_FRAGMENT = "MAP_FRAGMENT";
    public static final String FRAG_FEEDBACK = "FEEDBACK";
    public static final String FRAG_RATE_FRAGMENT = "RATE_FRAGMENT";

    public static final String USA_CODE = "+1";

    public static final String DISTANCE_SEARCH = "DISTANCE_SEARCH";


}

happy coding

  • I get some null value in some cases. (user gets the new message but the Uri for content resolver which stored like above method is null in some cases) – Amir Hossein Ghasemi Jun 03 '20 at 22:59
0

Property File

We store a property file under <project>/<package>/src/main/assets/config.properties

Loading properties

   private static final String PROPS_NAME = "config.properties";
   private static Properties configuration;

   ...
   public static void init(Context ctx) {

        configuration = new Properties();
        InputStream rawResource = resources.getAssets().open(PROPS_NAME);
        configuration.load(rawResource);