martes, marzo 05, 2019

Migrando Hacia AndroidX

Cuando en el Google IO del 2018 se anuncia el famoso Jetpack de Android, definitivamente fue la apertura de un mundo de posibilidades y cosas nuevas para ver en Android. Android Jetpack es un "compendio" o conjunto de librerías que los chicos de Google agruparon con el objetivo de mejorar el desarrollo en Android.

Pero todo ovillo tiene su punto inicial y en el caso de Jetpack, es Android X. Android X es - por fín!, el siguiente paso a las support libraries, con las que venimos trabajando en la actualidad (y me refiero como actualidad a este 2019 donde "todavía" las support libraries siguen vigentes).

Cuando abrimos el archivo gradle del módulo de nuestro proyecto, casi siempre estamos acostumbrados a encontrarnos con esto:

Android Studio, Gradle Module
Android Studio, Gradle Module

Y pasa el tiempo, las referencias no se actualizan y luego tenemos problemas de compatibilidad, porque si usamos la appcompat-v7:27.1.1 debemos mantener las versiones del resto de las librerías y entonces por ejemplo el Recyclerview "com.android.support:recyclerview-v7:27.1.1" debe seguir la misma línea y así sucesivamente. También hay definiciones que han quedado obsoletas como el "-v7" que posee la appcompat que originalmente indicaba la mínima versión de SDK necesaria y esto está completamente desactualizado, generado confusiones en los desarrolladores.

AndroidX que es el nombre resumido de "Android Extension Libraries", vienen a resolver estos problemas simplificando varias cosas!

En primer lugar, las existentes Support Libraries se encuentran mapeadas dentro de Androidx, con lo cuál, nada se pierde, todo se transforma. Para quienes quieran ir al detalle del mapeo entre librerías, les dejo el siguiente link con la tabla de mapeo:

https://developer.android.com/jetpack/androidx/migrate

A diferencia de las Support Libraries, AndroidX se mantienen y actualizan por separado con lo cuál si bien ahora en el inicio quizás veamos el mismo número de versión, luego según cada widget vaya tomando mejoras, los números de versión serán diferentes entre sí, sin generar ningún tipo de problema.

Entonces, si crearon un proyecto en los últimos meses usando Android Studio 3.2.1 o superior, donde el target version es API 28 y la versión del plugin de Gradle es 3.2.0 o superior, no tendrán problema en ejecutar el proceso de migración a AndroidX, tan simple como:

Botón derecho sobre el archivo gradle.
Refactor -> Migrate to Android X.

Aparecerá un popup como el siguiente invitándolos a a hacer un backup, dependiendo de la importancia del proyecto quizás es recomendable hacerlo, sino, pueden omitir este paso y ejecutar el proceso.

AndroidX proceso de migración ~ popup de confirmación
AndroidX proceso de migración ~ popup de confirmación
Una vez ejecutado el proceso, el cambio se visuliza de la siguiente manera:

ANTES:

build.gradle (Module:app) ~ Antes del Cambio a AndroidX
build.gradle (Module:app) ~ Antes del Cambio a AndroidX


DESPUES:

build.gradle (Module:app) ~ Después del Cambio a AndroidX
build.gradle (Module:app) ~ Después del Cambio a AndroidX


Como parte de esta migración, hay algunos agregados, si por ejemplo le damos una mirada al archivo gradle.properties:

gradle.properties
gradle.properties


Vemos que useAndroidX se encuentra en true y también enableJetifier que se encarga de traducir librerías de terceros que quizás usemos en nuestro proyecto y que no estén actualizadas a AndroidX para que todo siga funcionando sin problemas.

Notarán que ahora en el código de cada clase, las referencias de widgets son a AndroidX:

MainActivity.kt
MainActivity.kt


Si la versión del plugin de Gradle no es 3.2.0 o superior y/o el target version del proyecto no es 28, les aparecerá un mensaje de error y deberán modificar estos valores, como por ejemplo lo debo hacer aquí, en el archivo build.gradle del proyecto, para llevarlo a la última versión del plugin de gradle:

build.gradle (del proyecto) ~ upgrade del build tools
build.gradle (del proyecto) ~ upgrade del build tools


Es probable que luego de hacer este cambio no solo se recompile el proyecto sino que les de la opción de hacer un "fix" completo del proyecto para compatibilizar por completo todas las versiones, si bien suena complejo, es solo darle clic al link que nos proporciona en el logcat.

Desde la última versión de Android Studio 3.3, cuando se crea un proyecto ya se puede elegir la opción de ir por AndroidX:

Android Studio 3.3.1 ~ Creando un proyecto
Android Studio 3.3.1 ~ Creando un proyecto


Tal y como Google viene empujando los cambios y novedades en los últimos años, todo indicaría que en una no muy lejana versión de Android Studio, ya los proyectos se crearían bajo esta nueva versión de librerías, dejando atrás el modelo actual.

Referencia Android Developer: https://developer.android.com/jetpack/androidx

lunes, septiembre 25, 2017

Android Studio 3 (Beta 6): 6 novedades para destacar

Android Studio 3 "Beta 6" se encuentra disponible y siendo que parece haber varias novedades decidí armar un artículo con al menos algunas de las características que creo conveniente resaltar de lo que se viene. La estética en general cambió .

Creación de Proyectos

Por empezar, al crear un nuevo proyecto tenemos algo que nos habían prometido..., la posibilidad de incorporar Android Things algo no menor para quienes estamos trabajando o investigando sobre el tema.


Kotlin

Como no podía ser de otra forma lo primero a destacar es que Kotlin ya se encuentra incluido en Android Studio 3 y con esto me refiero es que, al igual que en su momento agregaron un checkbox con "support C++" ahora agregaron uno con "support Kotlin"..., una vez seleccionado, todo el proyecto ya queda en Kotlin.


No más"findViewById" (Kotlin Only)

Así es, para quienes reniegan de tener que hacer el tedioso findViewById y quizás también de tener que incluir librerías como Butterknfife para poder evitarlo, Android Studio 3 ya permite esto lamentablemente solo de la mano de Kotlin. Es decir, si tu proyecto ya lo realizas en Kotlin, acceder al valor de un EditText del layout es tan simple como colocar del lado del código el nombre del componente y listo ejemplo, editText.text = "Hola Mundo".



Peeerooo...., momento! Noten que (TextView) está remarcado... y cuando pongo el puntero del mouse por encima aparece la lamparita amarilla que me dice que "el casteo es redundante", en efecto...., ya no es necesario hacer el cast del findViewById, directamente el mismo retorna el tipo de objeto del elemento:


Opciones en el ConstraintLayout

Cuando hacemos clic derecho sobre un componente dentro de un layout con ConstraintLayout actualmente aparecen una enorme cantidad de opciones de alineación y otras utilidades. Ahora siguen las mismas, pero al menos las agruparon por algún tipo de criterio basado en si con utilidades de alineación de componentes, guías o posicionamiento. Lo mismo para en la barra de arriba cuando estoy en la vista de diseño. Es útil ya que ahora el desplegable es más corto y más simple de visualizar.

Errores y Warnings del Layout mucho mas amigables

Los errores o warnings del layout que solíamos tener como un icono arriba a la derecha y muy poco accesible, ahora si bien se siguen mostrando ahí para los problemas mas generales, lo particular se muestra en el Component Tree. Nice!


Merged Manifest

Algo un poco "bizarro" pero quizás útil, es que al abrir el xml del AndroidManifest, ahora tenemos una segunda solapa que dice "Merged Manifest". Lo que hace es justamente hacer una vista conjunta (o merge) entre los datos de configuración que tenemos en el manifest y los del gradle volviendo a tener al mejor estilo "Manifest del Eclipse" una visión global de los parámetros de configuración de la aplicación sin tener que estar viendo 2 archivos. Podemos ver en un solo lado tanto las actividades declaradas, los permisos, como la versión del código, el compile versión, min-sdk, target-sdk, etc. Pero...., no se puede editar, es solo una vista.


Profiler

El profiler ahora tiene un ícono arriba en la barra junto con los accesos que usamos diariamente:


Al hacerle clic, se abre el Android Profiler que parece haber tenido algunas mejoras, pero son más que nadas visuales:


Veremos cuánto tiempo más sigue en Beta y si habrá alguna novedad más. Para quienes desean ser un "Early Adopter" y probar todo lo nuevo, les dejo el link aquí:


lunes, agosto 21, 2017

Android con Kotlin: Usando Lambda Expressions

Las expresiones lambda (o lambda expressions) que veremos en Kotlin, no son en realidad una completa novedad..., en Java se pueden usar y es algo que otros lenguajes como C# ya lo tienen desde aproximadamente el año 2006 (con .Net 3.0).

Pero, ¿que son las expresiones lambda?

Las expresiones lambda permiten pasar funcionalidad como argumento de una forma muy simple y sin tener que usar clases anónimas. Esto hace que simplifique mucho la codificación.

Supongamos que tenemos la siguiente función:

fun compare(a: String, b: String): Boolean = a.length < b.length

Mediante una expresión lambda se podría hacer los siguiente:

max(strings, { a, b -> a.length < b.length })

"max" es una función que toma el valor del segundo argumento, donde este segundo argumento es en sí, una función.

El formal en general de una expresión lambda es:

{
  param1, param2 -> //parámetros separados por coma
  param1 + param2 //código a ejecutar
}

Para terminar de ver esto con un ejemplo bien práctico, primero tomemos como referencia la implementación de un "OnItemClicListener" en un ListView en Java, tradicionalmente se vería de la siguiente manera:

mListView.setOnItemClickListener(new OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view,
  int position, long id) {

  Log.d("onItemClick", "Se hizo clic") // Acá va la acción a realizar.

  }
});

Con un lambda expression en Kotlin, se simplificaría de esta manera:

mListView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->

    Log.d("onItemClick", "Se hizo clic") // Acá va la acción a realizar.

}

Como se puede apreciar, la diferencia en simplicidad y reducción de código es sumamente apreciable. No obstante, supongamos que view y id sean parámetros los cuáles no se les dará uso, la expresión podrían simplificarse aún más reemplazando esas argumentos que no estarán en uso por un "underscore":

mListView.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->

    Log.d("onItemClick", "Se hizo clic") // Acá va la acción a realizar.

}

Aún mejor, supongamos el siguiente clásico ejemplo del OnClickListener de un botón en Java:

button.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v){

doSomething();

}
});

En Kotlin, se reduce a una sola línea:

button.setOnClickListener({ view -> doSomething() })

Si los parámetros no son usados, directamente en lugar de reemplazarlos por un underscore, puede quitarlos, quedando:

button.setOnClickListener({ doSomething() })

Finalmente, como la función parámetro es única y el lambda también, puedo quitar los paréntesis quedando:

button .setOnClickListener { doSomething() }

Algo para destacar es que el mismo Android Studio nos va guiando y, si encuentra que podemos reemplazar el código que escribimos por una expresión lambda, nos lo siguiente actualizarlo en forma automática de la mano de la "lamparita amarilla" que usualmente aparece sobre el margen izquierdo de nuestro código.

Android Studio Kotlin Lambda Expression

Se puede ver un ejemplo completo e implementado de esto y otros temas más, en la siguiente aplicación que dejé completa en Github: