Best practice for declaring constants that are used in several Activities - android

In several tutorials, I've seen result codes set as "private static final int"s at the top of pertaining activities. To me this does not seem like the best way to do this since I find myself having to constantly refer to other classes to find the correct code rather than referring to the same code created somewhere else.
Is there a better way to do this? Is it bad practice to just make a utility class to hold the common result codes, request codes, data keys, etc? I've just never seen this done before.

Another way is to keep this variables in Gradle build and use them like this: BuildConfig.VARIABLE
Example:
In gradle file:
buildTypes {
release {
buildConfigField "java.lang.String", "DATABASE_NAME", "\"db_name\""
}
}
In Java:
BuildConfig.DATABASE_NAME
Pros:
can change constants values for different builds
there is one place with all program constants
auto generated (BuildConfig) by IDE/Gradle
References:
0.14.3 http://tools.android.com/tech-docs/new-build-system
http://toastdroid.com/2014/03/28/customizing-your-build-with-gradle/

I think it's personal preference, although it seems more meaningful to have all your statics in utility class. The tutorials probably show them in Activies for simplicity which is far easier to understand than using utility classes when they only need a couple of statics.

If you need to share constants for few classes, you can create special "constants" class and refer to it.
package ru.kopeyko.***;
/**
* class for holding various CONSTANTs for '***' app
*
* #author Andrey Kopeyko <andrey#kopeyko.ru>
*/
public final class Const {
public static final String UUID_DEFAULT = "00000000-0000-0000-0000-000000000000";
public static final String VERSION_CODE = "versionCode";
public static final long ONESECOND = 1000L;
public static final int POSITIONS_MAX_DAYS = 32;
public static final long DB_MAINTENANCE_INTERVAL = 1*86400*1000L;
}

Related

Are static methods a bad pratice? [duplicate]

I have a class that consists only of static member variables and static methods. Essentially, it is serving as a general-purpose utility class.
Is it bad practice for a class to contain only static member variables and static methods?
No, I don't think so at all. It is worse practice to have a class full of instance methods which don't actually depend on a particular instance. Making them static tells the user exactly how they are intended to be used. Additionally, you avoid unnecessary instantiations this way.
EDIT: As an afterthought, in general I think its nice to avoid using language features "just because", or because you think that that is the "Java way to do it". I recall my first job where I had a class full of static utility methods and one of the senior programmers told me that I wasn't fully harnessing the OO power of Java by making all of my methods "global". She was not on the team 6 months later.
As long as the class has no internal state and is essentially what is known as a leaf class (utility classes fall into this category), in other words it is independent of other classes. It is fine.
The Math class being a prime example.
Sounds reasonable.
Note: Classes that do this often have a private no-arg constructor just so that the compiler yields an error if a programmer tries to create an instance of the static class.
Static methods don't worry me much (except for testing).
In general, static members are a concern. For example, what if your app is clustered? What about start-up time -- what kind of initialization is taking place? For a consideration of these issues and more, check out this article by Gilad Bracha.
It's perfectly reasonable. In fact, in C# you can define a class with the static keyword specifically for this purpose.
Just don't get carried away with it. Notice that the java.lang.Math class is only about math functions. You might also have a StringUtilities class which contains common string-handling functions which aren't in the standard API, for example. But if your class is named Utilities, for example, that's a hint that you might want to split it up.
Note also that Java specifically introduced the static import: (http://en.wikipedia.org/wiki/Static_import)
Static import is a feature introduced
in the Java programming language that
members (fields and methods) defined
in a class as public static to be used
in Java code without specifying the
class in which the field is defined.
This feature was introduced into the
language in version 5.0.
The feature provides a typesafe
mechanism to include constants into
code without having to reference the
class that originally defined the
field. It also helps to deprecate the
practice of creating a constant
interface: an interface that only
defines constants then writing a class
implementing that interface, which is
considered an inappropriate use of
interfaces[1].
The mechanism can be used to reference
individual members of a class:
import static java.lang.Math.PI;
import static java.lang.Math.pow;
or all the static members of a class:
import static java.lang.Math.*;
While I agree with the sentiment that it sounds like a reasonable solution (as others have already stated), one thing you may want to consider is, from a design standpoint, why do you have a class just for "utility" purposes. Are those functionals truly general across the entire system, or are they really related to some specific class of objects within your architecture.
As long as you have thought about that, I see no problem with your solution.
The Collections class in Java SDK has static members only.
So, there you go, as long as you have proper justification -- its not a bad design
Utility methods are often placed in classes with only static methods (like StringUtils.) Global constants are also placed in their own class so that they can be imported by the rest of the code (public final static attributes.)
Both uses are quite common and have private default constructors to prevent them from being instantiated. Declaring the class final prevents the mistake of trying to override static methods.
If by static member variables you did not mean global constants, you might want to place the methods accessing those variables in a class of their own. In that case, could you eleborate on what those variables do in your code?
This is typically how utility classes are designed and there is nothing wrong about it. Famous examples include o.a.c.l.StringUtils, o.a.c.d.DbUtils, o.s.w.b.ServletRequestUtils, etc.
According to a rigid interpretation of Object Oriented Design, a utility class is something to be avoided.
The problem is that if you follow a rigid interpretation then you would need to force your class into some sort object in order to accomplish many things.
Even the Java designers make utility classes (java.lang.Math comes to mind)
Your options are:
double distance = Math.sqrt(x*x + y*y); //using static utility class
vs:
RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.
Even if we were to avoid the verbose method, we could still end up with:
Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);
in this instance, .sqrt() is still static, so what would the point be in creating the object in the first place?
The answer is, create utility classes when your other option would be to create some sort of artificial "Worker" class that has no or little use for instance variables.
This link http://java.dzone.com/articles/why-static-bad-and-how-avoid seems to go against most of the answers here. Even if it contains no member variables (i.e. no state), a static class can still be a bad idea because it cannot be mocked or extended (subclassed), so it is defeating some of the principles of OO
I wouldn't be concerned over a utility class containing static methods.
However, static members are essentially global data and should be avoided. They may be acceptable if they are used for caching results of the static methods and such, but if they are used as "real" data that may lead to all kinds of problems, such as hidden dependencies and difficulties to set up tests.
From TSLint’s docs:
Users who come from a Java-style OO language may wrap their utility functions in an extra class, instead of putting them at the top level.
The best way is to use a constant, like this:
export const Util = {
print (data: string): void {
console.log(data)
}
}
Examples of incorrect code for this rule:
class EmptyClass {}
class ConstructorOnly {
constructor() {
foo();
}
}
// Use an object instead:
class StaticOnly {
static version = 42;
static hello() {
console.log('Hello, world!');
}
}
Examples of correct code for this rule:
class EmptyClass extends SuperClass {}
class ParameterProperties {
constructor(public name: string) {}
}
const StaticOnly = {
version: 42,
hello() {
console.log('Hello, world!');
},
};

How to structure an app with many activities?

I am making an application presenting a showroom and at this points I have created way too much classes.
The main view is a GridView containing all the series of cars.(Each GridView Item opens a new class, so there are 9 classes with very similar code)
How can I structure it?
To put a bit more flesh on #g00dy, start by creating a class
class BMW {
// Reference codes for every series
public final static int SERIES_1 = 0;
public final static int SERIES_2 = 1;
// etc
public final static int NUMBER_SERIES = 9;
// All the code needed for every car
// eg.
public String giveManufacturuer() {
return "BMW"; // But see #g00dy - use string resources
}
public String giveSeries() {
return XXXXX; // Depends on which approach you choose, see below
}
public String giveModelName() {
return XXXXX; // Depends on which approach you choose, see below
}
}
You can either load all the variations into this class (add in references codes for every car and set up some tables to make indexing easy).
Or you could extend the class using inheritance for each class:
class Series1 extends BMW {
#Override
public String giveSeries {
return "Series 1";
}
}
class Series1M3Door extends Series1 {
#Override
public String giveModelName {
return "3 Door";
}
}
When you then instantiate the final class it will have all three functions working correctly.
This approach is neat, but will still give you a lot of classes. I suspect that for what you are doing, some well thought out information tables (accessed by series and model code) may work better inside a hidden class.
A different, perhaps better approach, might be to structure the code using the information that you are returning as the core classes.
I do not actually have the time to write all this down, mean a unifying class, but here's hint for you. Use a flag, which will indicate the model of the car (Z4,M6 for example), then use it inside the class to determine the tree on which the code should run. Replace the hardcoded values with string resources (just do it, no other remarks are necessary). When instantiating the class and using it's functions, take into account the flag and put it inside an if() condition or inside a switch. If some models require more code than the others, you can always encapsulate it in the part of the code which is responsible for the model. But avoid nesting too much ifs, because it will get messy, like having 100 classes defined which do 99% the same thing as the others. Always try to re-use your code as much as possible. It will reduce the writing (copy/pasting) repetitive stuff, also the size of the application, the memory it will need etc. Conclusion: try combining the common parts of the classes into one class ( to RULE THEM ALL :-) ) and use flags, to let the program knwo what to do there.

Which is best way to define constants in android, either static class, interface or xml resource?

I'm developing an android application which uses web service to get data from server, for that I'm having three different set of URLs to point development system, test server and live server. It's difficult to change URL whenever I want to give application for testing/live. so I planned to make it as configurable, so that application can get appropriate URL based on me build type configuration constant.
So,
which is the best way to keep this constants, java static class or
java public interface or xml resource file.? When? Why?
which gives better performance?, When? Why?
Ex: xml resource
<integer name="config_build_type">0</integer>
<string-array name="url_authentication">
<item >http://development.com/xxxx</item>
<item >http://test.com/xxx</item>
<item >http://example.com/xxx</item>
</string-array>
Java static constant
public class Config {
public static final int BUILD_TYPE = 0; // 0 - development, 1 - test, 2 - live
public static final String[] URL_AUTHENTICATION = {"http://development.com/", "http://test.com/", "http://example.com"};
}
There is a big difference between the two in that you can reference project resources in your XML layouts. They are available in the application context and are therefore accessible across the global application. The biggest advantages of using project resources is the ease of access and that they allow you to organize your project significantly.
static final constants are compiled into the java bytecode; project resources are compiled into a binary format within the apk. Accessing either is extremely efficient... if there is a difference between the two, it is trivial at most.
There isn't a set rule on how you should be using resources/constants in your project. That said, I personally use resources for values that I might need to use in my XML or java code. On the other hand, I typically use static final constants for values that will only be used by my java code and are specific to my implementation.
Also note that it is possible to load XML resources at runtime depending on the device's current configuration (i.e. screen size, locale, etc.). So you should take this into consideration when deciding whether or not you should declare the constant in XML or directly in your .java files.
For the people who want to see how we can use a Class to define our constants and call any where we need.
Constant.java
package org.nrum.nrum;
/**
* Created by rajdhami on 5/23/2017.
*/
public class Constant {
public static final String SERVER = "http://192.168.0.100/bs.dev/nrum";
// public static final String SERVER = "http://192.168.100.2/bs.dev/nrum";
public static final String API_END = SERVER + "/dataProvider";
public static final String NEWS_API = API_END + "/newsApi";
public static final String BANNER_API = API_END + "/bannerApi/lists";
public static final String NOTICE_API = API_END + "/noticeApi/lists";
public static final String UPLOAD_PATH = SERVER + "/uploads";
public static final String UPLOAD_PATH_BANNER = UPLOAD_PATH + "/company_1/banner";
public static final String UPLOAD_PATH_NEWS = UPLOAD_PATH + "/company_1/news";
public static final int BANNER_TRANSITION_DURATION = 5000;
public static final int NOTICE_BUTTON_BLINK_DURATION = 5000;
public static final int BANNER_FETCH_LIMIT = 3;
}
Now we can use above constants in following way.
Constant.NOTICE_BUTTON_BLINK_DURATION
In general case:
XML values have the advantage of accessbilty in layout file and manifest file over Constants in java file
XML values have the advantage for multi language support over Constants in java file
It’s always a good practice to extract UI strings from your app code and keep them in an external file. Android makes this easy with a resources directory in each Android project.
http://developer.android.com/training/basics/supporting-devices/languages.html
I think both way seems to be good but thing is that it depends on your requirements.
If you have your values(web service link) in your XML and suppose there is any change in your values(web service link) , you can easily change only in XML file.
But if you use inside classes as static variables you have to change in all class files.
So my suggestion is that separate constants from source file and put into resource and access it..
If the constant related or depend on locale or language or use in manifest you may consider to use xml values
If the constant dont't related to translation or locale or use in manifest I would avoid to put it in xml resource
I would add enum inside the viewmodel or whatever that need to use constant as a key.
enum class Key{
key,rule,practice
}
Or
const val MY_CONST = "my constant"
In Kotlin:
class Foo() {
// any other code for the class Foo
companion object {
const val MY_CONSTANT = "my constant"
}
}
This method is particularly recommended for data object.
Project resources need access to Context, which is not available in static methods unless you pass it in, but is always available in Activities -- there seems to be a preferential connection between resources and layouts.
For app variables and constants that may be processed in static methods I create an abstract class and do a static import (of this constants class) in all the other project class files.

getResources() or create own static class?

I noticed myself constantly typing:
someVar = getResources().getString(R.string.someString);
I have several XML files that I am parsing and building and in order to make sure that the files stay consistent, I have placed the tag names in the res/values/strings.xml file. The same handles are used throughout several activities, and some of those activities extend ListActivity while others do not so creating a simple super class which houses these variables ( ex:
public class thisClass extends thatClass
{...}
public class thatClass
{
package String someTag = "this";
package String otherTag = "that";
}
I would assume that all of these calls to getResources() could get pretty taxing and was wondering if it is beneficial to instead create an R-type file where I can store these types of commonly used variables statically ex:
public final class globalVars
{
public static final class XML_TAGS
{
static final String someTag = "this";
static final String otherTag = "that";
}
}
and to reference these variables like such:
serializer.startTag("", globalVars.XML_TAGS.someTag);
instead of
serializer.startTag("", getResources().getString(R.string.someTag));
Thanks for the input!
OK, after looking into the source code of android.content.res.resources and some other classes, it is evident that using Resources and getting resources through getResources() is costly compared to a static class.
Indeed, the instance of Resources returned is not a static container but rather an object that gets resources by executing a couple of statements (whether a string or drawable or any other form).
However, using getResources() has its advantages:
It helps you externalize your resources.
For any type of resource, you can specify default and multiple alternative resources depending maybe on Locale, Screen Depth/Resolution...
A static container might provide a less costly alternative than using resources but remember: any later attempt at localization would be relatively extremely costly.

How to inherit global settings class in different Android projects

I have several different Android projects that use a library where I've created most of the common classes. One of the classes is "commonSettingsAndFunctions" where I've defined several static strings and methods to be used. Example:
public class commonSettingsAndFunctions {
public static String flurryCode = "MY_FLURRY_CODE";
public static final int APP_VERSION = 2;
public static final String API_URL = "http://mydomain/api.jsp"
public static String getAPIUrl(Context context, String parameters) {
// code
}
}
However, now I've come up with a situation where I have to change some of the settings per project. For example, flurry code and app version. API_URL is always (so far) the same.
What's the best way to implement this? One option I thought of is making commonSettingsAndFunction as abstract, create a class "commonSettingsAndFunctionsReal extends commonSettingsAndFunctions", then implement the "Real" class per project? Another possibilities?
I come from PHP world, and there I'd just have settings as a class, and do this in some "global include file":
$common = new commonSettingsAndFunctions();
$common->flurryCode = "ABCD";
AppVersion is something that is in the AndroidManifest.xml and you can access that from code, so you don't really need your own version of it. As fo the Flurry API key, I always put mine in my strings.xml so I can load it in when I need it.

Categories

Resources