I used to define a set of related constants like Bundle keys together in an interface like below:
public interface From{
String LOGIN_SCREEN = "LoginSCreen";
String NOTIFICATION = "Notification";
String WIDGET = "widget";
}
This provides me a nicer way to group related constants together and used them by making a static import (not implements). I know Android framework also uses the constants in same way like Toast.LENTH_LONG, View.GONE.
However, I often feel that the Java Enums provide much better and powerful way to represent the constant.
But is there a performence issue in using enums on Android?
With a bit of research I ended up in confusion. From this question
"Avoid Enums Where You Only Need Ints” removed from Android's performance tips? it's clear that Google has removed "Avoid enums" from its performance tips, but from it's official training docs Be aware of memory overhead section it clearly says: "Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android." Is this still holds good? (say in Java versions after 1.6)
One more issue that I observed is to send enums across intents using Bundle I should send them by serializing (i.e putSerializable(), that I think an expensive operation compared to primitive putString() method, eventhough enums provides it for free).
Can someone please clarify which one is the best way to represent the same in Android? Should I strictly avoid using enums on Android?
Use enum when you need its features. Don't avoid it strictly.
Java enum is more powerful, but if you don't need its features, use constants, they occupy less space and they can be primitive itself.
When to use enum:
type checking - you can accept only listed values, and they are not continuous (see below what I call continuous here)
method overloading - every enum constant has its own implementation of a method
public enum UnitConverter{
METERS{
#Override
public double toMiles(final double meters){
return meters * 0.00062137D;
}
#Override
public double toMeters(final double meters){
return meters;
}
},
MILES{
#Override
public double toMiles(final double miles){
return miles;
}
#Override
public double toMeters(final double miles){
return miles / 0.00062137D;
}
};
public abstract double toMiles(double unit);
public abstract double toMeters(double unit);
}
more data - your one constant contains more than one information that cannot be put in one variable
complicated data - your constant need methods to operate on the data
When not to use enum:
you can accept all values of one type, and your constants contain only these most used
you can accept continuous data
public class Month{
public static final int JANUARY = 1;
public static final int FEBRUARY = 2;
public static final int MARCH = 3;
...
public static String getName(final int month){
if(month <= 0 || month > 12){
throw new IllegalArgumentException("Invalid month number: " + month);
}
...
}
}
for names (like in your example)
for everything else that really doesn't need an enum
Enums occupy more space
a single reference to an enum constant occupies 4 bytes
every enum constant occupies space that is a sum of its fields' sizes aligned to 8 bytes + overhead of the object
the enum class itself occupies some space
Constants occupy less space
a constant doesn't have a reference so it's a pure data (even if it's a reference, then enum instance would be a reference to another reference)
constants may be added to an existing class - it's not necessary to add another class
constants may be inlined; it brings extended compile-time features (such as null checking, finding dead code etc.)
If the enums simply have values, you should try to use IntDef/StringDef , as shown here:
https://developer.android.com/studio/write/annotations.html#enum-annotations
Example: instead of :
enum NavigationMode {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}
you use:
#IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
#Retention(RetentionPolicy.SOURCE)
public #interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
and in the function that has it as a parameter/returned value , use:
#NavigationMode
public abstract int getNavigationMode();
public abstract void setNavigationMode(#NavigationMode int mode);
In case the enum is complex, use an enum. It's not that bad.
To compare enums vs constant values, you should read here:
http://hsc.com/Blog/Best-Practices-For-Memory-Optimization-on-Android-1
Their example is of an enum with 2 values. It takes 1112 bytes in dex file compared to 128 bytes when constant integers are used . Makes sense, as enums are real classes, as opposed to how it works on C/C++ .
With Android P, google has no restriction/objection in using enums
The documentation has changed where before it was recommended to be cautious but it doesn't mention it now.
https://developer.android.com/reference/java/lang/Enum
In addition to previous answers, I would add that if you are using Proguard (and you should definitely do it to reduce size and obfuscate your code), then your Enums will be automatically converted to #IntDef wherever it is possible:
https://www.guardsquare.com/en/proguard/manual/optimizations
class/unboxing/enum
Simplifies enum types to integer constants, whenever possible.
Therefore, if you have some discrete values and some method should allow to take only this values and not others of the same type, then I would use Enum, because Proguard will make this manual work of optimizing code for me.
And here is a good post about using enums from Jake Wharton, take a look at it.
As a library developer, I recognize these small optimizations that should be done as we want to have as little impact on the consuming app's size, memory, and performance as possible. But it's important to realize that [...] putting an enum in your public API vs. integer values where appropriate is perfectly fine. Knowing the difference to make informed decisions is what's important
Should I strictly avoid using enums on Android?
No. "Strictly" means they are so bad, they should not be used at all. Possibly a performance issues might arise in an extreme situation like many many many (thousands or millions of) operations with enums (consecutive on the ui thread). Far more common are the network I/O operations that should strictly happen in a background thread.
The most common usage of enums is probably some kind of type check - whether an object is this or that which is so fast you won't be able to notice a difference between a single comparison of enums and a comparison of integers.
Can someone please clarify which one is the best way to represent the same in Android?
There is no general rule of thumb for this. Use whatever works for you and helps you get your app ready. Optimize later - after you notice there's a bottleneck that slows some aspect of your app.
I like to add, that you can not use #Annotations when you declare a List<> or Map<> where either key or value is of one of your annotation interfaces.
You get the error "Annotations are not allowed here".
enum Values { One, Two, Three }
Map<String, Values> myMap; // This works
// ... but ...
public static final int ONE = 1;
public static final int TWO = 2;
public static final int THREE = 3;
#Retention(RetentionPolicy.SOURCE)
#IntDef({ONE, TWO, THREE})
public #interface Values {}
Map<String, #Values Integer> myMap; // *** ERROR ***
So when you need to pack it into a list/map, use enum, as they can be added, but #annotated int/string groups can not.
Two facts.
1, Enum is one of the most powerful feature in JAVA.
2, Android phone usually has a LOT of memory.
So my answer is NO. I will use Enum in Android.
Related
I have an enum like this:
public enum Type {
VIDEO(10,"video"),
AUDIO(11,"audio");
int code;
String desc;
Type(int code,String desc){
this.code = code;
this.desc = desc;
}
}
But , Enumerations are not recommended in Android,How to do it with typedef, or is there another better way?
You can using #IntDef but still need method to convert code to desc. But take a look article from Google Developer, he said now enum isn't a big deal, not overhead memory and already optimize by R8 read here
#Retention(SOURCE)
#IntDef({VIDEO,AUDIO})
public #interface Type {}
public static final int VIDEO = 10;
public static final int AUDIO = 11;
#Type int type
In your example enum, you don't really need desc value, since you can use name() method (and even toString()), for example
final String desc = Type.VIDEO.name();
you could turn String result to lower/upper case as your convenience.
On the other hand, #IntDef is a way of replacing an integer enum where there's a parameter that should only accept explicit int values. If you have a parameterized enum with multiple hardwired values, like yours VIDEO(10,"video", "etc...") you should consider use the enum.
You can also create an annotation using a custom class and then use it in the same way as someone mentioned in this response Convert parametized Enum to Enumerated Annotation in android
I have never tried R8 yet, as #Công Hải mentioned, and evaluate its performance on enums. You will find multiple articles about how bad are enums for your app, and they most seem quite right. But don't avoid it strictly. I would try to use #IntDef or #StringDef, as much as I could, but it is not always simple. My adivice, you should analyze if you want to lose code readability for avoiding enums, or suffer for the overhead they may cause. You can always try.
Enums are no longer an issue for Android thanks to the replacement of Dalvik as runtime environment by ART. You can find more information about it in this Google IO video from 2018: https://www.youtube.com/watch?v=IrMw7MEgADk&t=849s - If you don't want to watch the whole vid you can fast forward to the minute 14:09.
Plus, thanks to R8, most enums are optimised at compile time too: https://jakewharton.com/r8-optimization-enum-ordinals-and-names/
So go ahead and your Enums :) they make the code more concise, easier to understand and less error-prone than other options.
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!');
},
};
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;
}
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.
inside of a single activity, when defining components to be used only within that activity, what's the real difference between the following definitions:
Button btnPower = null;
//or
private Button btnPower = null;
//or
public Button btnPower = null;
public void somethingUsingTheButton(){
btnPower = (Button)findViewById(R.id.btnpower_id);
}
are there some "under the hood" conventions that should be thought about (garbage cleanup, memory, etc) that would suggest to always use private over public, if the entity itself is only ever going to be used inside the class it's written in?
Private fields promote encapsulation
It's a generally accepted convention to use private unless you need to expose a field or method to other classes. Getting in this as a habit will save you a lot of pain in the long run.
However, there isn't anything inherently wrong with a public field or method. It causes no difference for garbage collection.
In some cases some types of access will affect performance, but they are probably a bit more advanced than the topic of this question.
One such case has to do with inner classes accessing outer class fields.
class MyOuterClass
{
private String h = "hello";
// because no access modifier is specified here
// the default level of "package" is used
String w = "world";
class MyInnerClass
{
MyInnerClass()
{
// this works and is legal but the compiler creates a hidden method,
// those $access200() methods you sometimes see in a stack trace
System.out.println( h );
// this needs no extra method to access the parent class "w" field
// because "w" is accessible from any class in the package
// this results in cleaner code and improved performance
// but opens the "w" field up to accidental modification
System.out.println( w );
}
}
}
well,
one important point is that defining variables as private is the standard in java programming.
So calling directly variables on objects will at least appear strange for other people that may possibly read your code.
One other thing I'd say is that if you are not alone coding on a project is always a good practice to limit the visibility of the attributes that are key on the class implementation to avoid strange work around that other developers may come up with.
I personally don't know if those modifiers are used to compiling and optimization purpose.
to conclude as I think every experienced java coder I strongly sujest to use this pattern in the definition of attributes.
The scope of visibility has nothing to do with the garbage collector or memory management
You will want to reduce the scope of visibility as much as possible so your code can be easier to maintain.
private and public are both keywords of Java that have the purpose of Object Orientated Design. I suggest you read up about this: http://docs.oracle.com/javase/tutorial/java/concepts/
If you are only going to use those variables (objects) in your activity, then I would suggest you make those variables private.
I hope this helps.
Edit:
I'm not sure if using the private, public or no keyword will optimize you app from a memory point of perspective. As far as I can tell I think it does not and you should use what makes your code most readable, intuitive and maintainable.
If your variable declaration is inside the Activity's scope, it acts normally as a scoped variable normally would.
It is, however, bad programming practice to use variables from one method in another method when they're not parameters.
Example:
Bad:
void Foo()
{
int foo = 5;
System.out.println(Bar());
}
int Bar()
{
return foo + 5;
}
This will actually throw a syntax error because foo is declared outside of scope for Bar()
Good:
int foo;
void Foo()
{
foo = 5;
System.out.println(Bar(foo)); //prints 10
}
int Bar(int foo)
{
return foo + 5;
}