Porque usar @IntDef en vez de Enums en Android

Hace un par de días un amigo me mostró el video de Colt McAnlis donde habla de los ENUMs en Android y el porque parecen ser una gran idea hasta que se ejecuta y analiza la aplicación.

De los problemas que comenta Colt, los mas graves son la cantidad de memoria que se ocupa en comparación al uso de enteros (13x) y la memoria extra que se tiene que usar para el manejo de cada Arreglo y de cada elemento que contienen los propios arreglos.

Los ENUMs son muy usados para tratarlos como enteros y tener una mejor comprensión de la lectura del código, por lo que recomiendan que usemos la anotación @intDef para realizar las mismas funciones que realizarías con un ENUM pero con los beneficios de usar Int.

Para este caso en particular compartiré un ejemplo de como usarlos desde una Clase llamada ConstantUtils y de ahí usarlo como si fuera un ENUM:

public class ConstantUtils {

public static final int POPULAR = 0;
public static final int NEW = 1;
public static final int TOP_RATED = 2;
public static final int UPCOMING = 3;
public static final int FAVORITE = 4;

@IntDef({POPULAR, NEW, TOP_RATED, UPCOMING, FAVORITE})
@Retention(RetentionPolicy.SOURCE)
public @interface FilterMovie{}

}

Ahora lo usaré en otra clase:

public class GridMoviesPresenterImpl {
......
private @ConstantUtils.FilterMovie int mMovieFilter;

public GridMoviesPresenterImpl() {
mMovieFilter = POPULAR;
}

@Override
public void getMovies(int page) {

switch (getCurrentFilter()) {
case FAVORITE:
break;
case POPULAR:
break;
case TOP_RATED:
break;
default:
break;
}
}

@Override
public void setFilterType(int filter) {
this.mMovieFilter = filter;
}

@Override
public int getFilterType() {
return mMovieFilter;
}

@ConstantUtils.FilterMovie
public int getCurrentFilter() {
return mMovieFilter;
}

}

Estos son los pasos a seguir de cómo agregar los nuevos “ENUMs”:

1- Se declaran las variables que se van a utilizar:

public static final int POPULAR = 0;

2- Se agrega la anotación de @IntDef para declarar las constantes que podremos utilizar.

@IntDef({POPULAR, NEW, TOP_RATED, UPCOMING, FAVORITE})

3- Declaramos el tipo de retención, por lo que tenemos que definirla como RetentionPolicy.SOURCE para que esté disponibles en tiempo de compilación y ejecución, de otra manera solo estará disponible en tiempo de compilación.

@Retention(RetentionPolicy.SOURCE)

4- Crear una interface para poder acceder al “Enum”

public @interface FilterMovie{}

Prácticamente con esto se puede cambiar los ENUMs por elementos de tipo entero.

Puedes encontrar un ejemplo en un proyecto que tengo público en el siguiente enlace.

Conclusión

El esfuerzo a realizar en el cambio es distinto dependiendo del tamaño del proyecto, pero vale la pena por integrar mejores prácticas en nuestros proyectos de Android y eliminar estos “Gremlins” .

Gracias!