miércoles, 29 de octubre de 2014

Nueva aplicación en el Google Play Store. Paletris




Recientemente he publicado en el Google Play Store mi nueva aplicación. Esta vez se trata de un juego, que tiene parte de puzzle y parte de agilidad y que a algunos podrá recordarles al famoso Tetris pero en realidad funciona de manera muy distinta.

En el mismo, deberás de acomodar bloques con letras dentro que van cayendo del cielo de manera que cuando los tengas en tierra puedas formar palabras uniendo algunos de ellos y ganando puntos, siguiendo hasta cierto punto para esto la lógica del Scrabble (formar una palabra con la ñ es mucho mas complicado que con la a, y en consecuencia deben de ser los puntos que se otorguen). Toda la acción la guía un gracioso Rinoceronte, fruto del trabajo del diseñador gráfico Abdel de la Campa.

Tecnológicamente hablando esta creado usando Android nativo y apoyándose en la librería RoboGuice. Además, hace uso del listado de palabras obtenidas con el método descrito aqui, desde el código fuente de Chrome.




Inyectando valores en las vistas en Android al estilo Roboguice o ButterKnife.

A la hora de desarrollar aplicaciones Android, soy un gran fanático de Roboguice. Este fue el que nos permitió pasar de

class EjemploActivity extends Activity {
TextView nombre;
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        nombre      = (TextView) findViewById(R.id.nombre); 

        //Utilizar findViewById con cast incluido para obtener el TextView
    }
}


a

class EjemploActivity extends RoboActivity {
    //Sencilla anotación que realiza la misma función

    @InjectView(R.id.nombre)             
    TextView nombre;
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

o sea, eliminar un montón de código de inicialización de nuestros vistas por medio de una simple anotación que le indica al framework que debe de hacerlo por nosotros. Lo malo de todo es que me gustó tanto, que al final acabé queriendo aplicar su filosofía a todo. Si no podía hacerlo como RoboGuice ya no estaba tan bien. Por ejemplo muchas veces me encontré queriendo cambiar la fuente de una vista y para esto tenía que hacer:

Typeface fuenteDeseada=Typeface.createFromAsset(getAssets(),"roboto");
nombre.setTypeface(fuenteDeseada);


Para esto me cree este proyecto. Con esta mini-librería es posible definir una anotación y en adición a esta definir una clase que implemente la funcionalidad esperada al encontrar declarada la anotación. De esta forma, después de haber declarado TypefaceInjector, podía tranquilamente hacer:

@InjectView(R.id.nombre)
 @InjectTypeface(typefaceName="roboto")
 private TextView nombre;

Y de manera similar con eventos y con muchas cosas más.

Tiempo después de desarrollar esto descubrí ButterKnife, cuyo código fuente es mucho mas sencillo de extender que RoboGuice y además tiene la particularidad que para el rellenado de las vistas utiliza generación de código en la compilación en lugar de Reflection, con la consecuente mejora de rendimiento. De haber conocido ButterKnife un poco antes, mi decisión hubiese sido extender este en lugar de crear SantaGuice, porque creo que este framework es realmente muy prometedor.

lunes, 20 de octubre de 2014

Creando e inicializando objetos complejos con datos de prueba

Te has encontrado alguna vez ante una clase como la siguiente:

public class Container {

List<ContentA> list1;
ContentB[] list2;
ContentC c3;
}

public class ContentA {

String strContent;
ContentB contentB;
}

public class ContentB {

int intContent;
ContentC cc;
}

public class ContentC {

Date dateContent;
}

Y te ves en la necesidad de instanciar un objeto de tipo Container con todos sus miembros con un cierto valor (puede ser aleatorio) para usarlo con cualquier fin, desde pasar un test hasta mockear la salida de un WebService que devuelve un POJO similar.

Yo he debido de hacerlo muchas veces, al principio solo tenía la opción de la "fuerza bruta", o sea

Container container=new Container();
container.setList1(new ArrayList());
container.setList2(new ContentB[5]);
container.setContentC(new ContentC());

container.getList1.add(...)
....

Tedioso no? Al tiempo me implemente una clase mía basada en la clase PropertyUtils de Apache Commons con las cuales inicializaba dinamicamente los objetos uno a uno, que represento un cierto avance con respecto a la solucion inicial pero todavia no era lo ideal.

Lo ideal lo descubrí en la libreria Podam la cual, a pesar de tener un interminable numero de configuraciones posibles para inicializar un objeto de la manera que mas nos guste, con dos sencillas lineas nos crea un nuevo objeto Container con todas sus propiedades rellenas tal y como queríamos.

PodamFactory factory = new PodamFactoryImpl();
//Usando la estrategia aleatoria de creación de objetos

Container container= factory.manufacturePojo(Container.class);

Y ya está. Simple no?

Comprobar si un número es impar, ¿Cual es la manera mas rápida?

Mi lectura de turno es el aunque medio añejo, muy recomendable libro Java Puzzlers . En este, los autores, que en su mayoría han estado ligados al desarrollo del lenguaje Java en alguna de sus fases nos plantean ejercicios que siempre parece que terminan de una forma y lo hacen de otra, sorprendiéndonos gratamente, desvelándonos alguna de las interioridades del lenguaje y haciéndonos conocerlos un poco mejor.

Uno de los ejercicios gira en torno a conocer en Java si un número es impar. La manera usual de obtener esto es mediante el operador % usando la expresión siguiente:

numero%2!=0

Este operador, en realidad calcula el resto de la división de numero entre 2 y por consiguiente de acuerdo a la especificación del lenguaje seria parte de la siguiente igualdad

numero/2+resto=división

a partir de la cual es calculado.

En Java Puzzlers se nos plantea la alternativa de saber si un número es impar si al aplicarle una operación Bitwise And con 1 como segundo operando devuelve algo distinto de 0

numero & 1!=0

El fundamento de esto es que el operador And Bitwise realiza un And entre las representaciones binarias de ambos operandos. El 1 al representarse en binario solo podrá dar como resultado un numero distinto de 0 al aplicarle un & Bitwise al ser comparado con un numero que también tenga un uno en la ultima posición en binario y estos numero tienen la forma 2n+1 o sea son impares.

000000001
&
________1
=
000000001

Para comprobar la veracidad del planteamiento se ha elaborado un mini programa que dado una entrada de 1 000 000 de números pone en practica ambos métodos para comprobar si son impares y el resultado como podrá verse comprueba lo planteado por los autores.

Ejecutando comprobacion con el mismo valor, 1000000 times
Via usual
Tardo 6 milisegundos
Via Bitwise
Tardo 0 milisegundos
Ejecutando comprobacion con 1000000 valores diferentes
Via usual
Tardo 5 milisegundos
Via Bitwise
Tardo 1 milisegundos



La ligera diferencia que existe entre el caso en el que los números son todos distintos y cuando son iguales no parece repetirse en sucesivos ejecuciones del programa por lo que no debería ser significativa. De esto puede extraerse que aunque usar el bitwise and pueda significar confuso a primera vista para posibles terceros que lean nuestro código, en ocasiones puede significar una mejora importante en el rendimiento de nuestras aplicaciones y es sin duda una cuestión que merece ser conocida por todos los amantes de un código eficiente y optimo.