[Groovy] SaveInstance en SwissKnife

Desde hace un par de meses he estado probando los beneficios y bondades del lenguaje de programación llamado Groovy.

Si a alguno no le suena o quiere saber algo más de él, le recomiendo encarecidamente que le eche un ojo al post de Arasthel sobre Por qué Java está viejuno.

Como ya sabréis si habéis leído el post de Arasthel, hay un plugin (en fase beta todavía) que permite desarrollar para Android utilizando Groovy.
Y aprovechando el soporte nativo de Groovy que ofrece Android Studio, sólo faltaba estar lo suficientemente loco como para probarlo.

SwissKnife

SwissKnife

Hay gente lo suficientemente loca como para desarrollar librerías utilizando un lenguaje en estado Beta (y no hablo de Swift) para que sean utilizadas en un entorno no soportado oficialmente. Y de una de esas locuras es de donde nace SwissKnife.

Imagino que si desarrolláis para Android, al menos conoceréis las famosas librerías AndroidAnnotations y ButterKnife, que basan su potencia en su uso mediante anotaciones.

Si desarrolláis para Android utilizando Groovy, siento deciros que no podréis utilizarlas, ya que únicamente funcionan en Java. Pero ahí es donde entra SwissKnife.

A modo de resumen (podéis leer más información en su README oficial), SwissKnife ofrece la posibilidad de tener la potencia de AndroidAnnotations y ButterKnife, pero portado nativamente a Groovy.

Dispone de métodos muy útiles como @InjectView, @OnClick, y recientemente se ha añadido el método @SaveInstance, el objetivo principal de este post.

@SaveInstance

Cualquiera que haya trabajado con Android y haya querido conservar variables en un cambio de estado (como puede ser por ejemplo la rotación de la pantalla), habrá tenido que lidiar con un código parecido a este:

@Override
public void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putInteger("MY_INTEGER", myInteger);
}

Y después, su correspondiente recuperación

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    // Your code
    if(savedInstanceState != NULL){
	    myInteger = savedInstanceState.getInteger("MY_INTEGER");
    }
}

Como este tipo de código es tedioso y repetitivo, Arasthel dijo que podríamos crear la anotación @SaveInstance para poder librarse de él.
Tras unos días de trabajo (desde aquí, gracias a Cédric Champeau y Guillaume Laforge, miembros del equipo de desarrollo de Groovy), el resultado ha quedado tal que así:

@SaveInstance
public int myInteger

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    SwissKnife.restoreState(this, savedInstanceState);
}

Y ya está. Sin tener que escribir manualmente el onSaveInstanceState, sin tener que comprobar si savedInstanceState era nulo o no...
Después solo tenemos que llamar al método SwissKnife.restoreState(this, savedInstanceState) y disfrutar viendo como SwissKnife lo hace todo de forma transparente, salvando su estado y manteniéndolo entre cambios de estado.

Además, en el caso de que queramos asignar una etiqueta determinada a una variable, podemos hacerlo simplemente pasándola como parámetro a la anotación.

@SaveInstance("MY_INTEGER")
public int myInteger

Cabe decir, además, que funcionará tanto si hemos hecho Override manualmente en el método onSaveInstanceState, como si ni siquiera lo hemos declarado.

Por supuesto, @SaveInstance soporta cualquier tipo de elemento que pueda ser escrito a un Bundle.

Documentación de @SaveInstance

And one more thing...

@SaveInstance puede utilizarse también para conservar el estado de las View.
Android por defecto ya lo hace automáticamente, pero únicamente si la view tiene una id asociada.
Con @SaveInstance se puede forzar el guardado y la restauración, incluso en View sin id.

@InjectView(R.id.edit_text)
@SaveInstance
public EditText myText;