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:


lunes, junio 05, 2017

Android: Comenzando con Koltin - Clases, Variables y el Safety Null

En mi artículo anterior (http://paveliz.blogspot.com.ar/2017/05/android-comenzando-con-kotlin.html) les dejaba no solo los primeros pasos para configurar Android Studio y poder comenzar a trabajar en Kotlin, sino también un ejemplo práctico (https://github.com/paveliz?tab=repositories), con el cual ya pudiesen ver y comparar lo que usualmente escribían en Java y cómo es que se escribe ahora en Kotlin.

Mi pendiente a comenzar a resolver en los siguientes artículos es comenzar a dejarles una base teórica con explicaciones puntuales del lenguaje y por supuesto, continuar dejando código útil en Github.

Entonces, comencemos a ver algunos temas propios del lenguaje:

Clases

En Java escribir una clase cuya función no es más quizás que describir un dato no es complejo, pero hay algunos elementos que debemos respetar, getter, setter, constructor, etc:

public class Alumno {

private Integer documento;
private String nombre;
private String apellido;

public Integer getDocumento() {
     return documento;
}

public void setDocumento(Integer documento) {
     this.documento = documento;
}

...

}

En Kotlin esto se resuelve de la siguiente forma:

open class Alumno constructor (
  var documento: Int,
  var nombre: String,
  var apellido: String
) {
  init {

  }
}

- Si el constructor principal no tiene ninguna annotation o modificador, la palabra "constructor" puede obviarse.
- El constructor principal puede no tener ningún código en particular, pero si se desea implementar una inicialización, se puede hacer en un bloque "init".
- Se genera automáticamente todas las propiedades, así como algunos métodos útiles como toString (), equals() y hashCode().

val nuevoAlumno = Alumno (1212, "Pepe Nombre", "Pepe Apellido")

Toast.makeText(this, "Propiedad Nombre: " + nuevoAlumno.nombre, Toast.LENGTH_LONG).show()

- Por default, todas las clases en Kotlin son como Java "final classes". El "open" delante de la clase justamente es lo opuesto al final y permite que pueda ser heredada.
- Obviamente si el constructor tiene argumentos, deberemos completarlos a la hora de aplicar la herencia.

class Pablo () : Alumno(1212, "Pablo", "Veliz")

Lo que teníamos como "métodos" en Java para darle cierta funcionalidad a nuestras clases, en Kotlin se llaman Functions (Funciones) y se precede por la palabra reservada "fun":

fun onCreate(savedInstanceState: Bundle?) {
...
}

En Kotlin, una función siempre retorna un valor, si no lo especificamos retorna Unit que sería el equivalente a "void" en Java. Solo que en Kotlin, Unit es un objeto. Si especificamos un valor de retorno quedaría:

fun calcularSuma ( a: Int, b: Int) : Int {
     return a + b
}

Otra cosa interesante que podemos hacer en Koltin es definir valor default para los argumentos:

fun calcularSuma ( a: Int, b: Int = 0 ) : Int {
     return a + b
}

Noten que entonces ahora, yo podría simplificar el tema y enviar solo el primer argumento a "calcularSuma", el segundo me lo toma por default como cero.

calcularSuma(2, 5)
calcularSuma(2)

var vs val

Como comenté en mi post anterior, Kotlin tiene de una forma más natural implementado los conceptos de "inmutabilidad" de las variables. ¿qué significa esto?, básicamente el concepto habla de que el valor de una variable NO pueda ser modificado luego de su inicialización. En Java, todas las variables/objetos mutan (a menos que estén indicadas explícitamente como "final"). Mutar significa básicamente, que cualquier otra parte del código podría modificar su valor.

En Kotlin usaremos "val" usualmente para justamente crear variables inmutables. De hecho, el propio Android Studio al ver que definimos una variable cuyo valor es luego modificado o caso contrario, nunca se modifica, hará automáticamente la sugerencia de cambiar un var a un val o viceversa.

Otro tema muy interesante en Kotlin es que NO necesito declarar los tipos, los mismos se infieren de su contenido.

// Variables Inmutables SIN Declaración de Tipo:
val pepe = "Algo"
val numero = 22

// Variables Inmutables CON Declaración de Tipo:
val otroPepe : String = "Algo"
val otroNumero : Int = 22

// Variables mutables
var pais = "Argentina"
var otroPais : String = "Argentina"


El famoso tema del Safety Null

Uno de los temas que más se comenta de Kotlin es que es "seguro" en el sentido de que no tiene previene los famosos "Null Pointer Exception" de Java. Es cierto..., aunque en realidad no es tan así. Para ejemplificar esto, lo voy a comentar aquí y dejé un ejemplo en Github ().

Cualquier operación que hagamos en Java con un elemento que puede llegar a tener un valor nulo, dará como resultado en Null Pointer Exception. Y esto es algo que, si bien podemos intentar predecir cuándo escribimos el código nos puede pasar igual y Android Studio o cualquier otro IDE de programación jamás nos dará advertencia alguna. Ejemplo:

public String nombre = null;

if (nombre.length > 0) {
...
}

PUM!!!

Definitivamente esto dará como resultado una excepción. Quizás no fue nuestra intención que nuestra variable "nombre" quedara en null, quizás fue producto de un "getStringExtra" que vino vacío justamente por haber olvidado validar un campo en el layout..., miles de razones pueden llevar a este conocido error.

Pero cuando desarrollamos en Kotlin, pasa lo siguiente:

var parametro: String? = null

La variable "parametro" se debe inicializar y si no sabemos si puede ser null o no, agregamos al final del tipo de dato el símbolo del signo de interrogación "?". Lo que le dice esto a Kotlin es: "bueno..., esta variable de tipo String podría tener un valor o podría ser null ¿quien sabe?".

Si luego quiero realizar una operación como con Java usando el lenght, tendremos el siguiente problema:

Automáticamente el mismo Android Studio nos dirá que hay un problema, ya que de entrada habíamos avisado que la variable podía contener nulos, no podemos entonces operar con la misma directamente. Algo que podríamos hacer sería esto:

var i: Int? = parametro?.length

¿que es esto? es una "safety operation" u operación "segura" como Kotlin lo llama. Básicamente, en ambos lados declaramos con el "?" que la operación puede dar null y esto NO dará Null Pointer Exception.

Si estamos completamente seguros que la variable es segura y no dará problema de nulos, Kotlin nos deja declararlo de la siguiente manera:

var i: Int = parametro!!.length

Noten que ahora, en lugar de usar el signo "?" usamos dos signos de explamación "!!". Con esto, lo que le estamos diciendo a Kotlin es: "Tranquilo, esta variable no tendrá NUNCA nulos y la operación es segura". Claro está, que si bien esto deja tranquilo y libre de warnings y errores a nuestro Android Studio..., si llegamos a fallar y la variable llega a tener un valor nulo...PUM! . En este caso tendremos un "Kotlin Null Pointer Exception"..., con lo cuál se darán cuenta

Una de las tantas formas correctas en las que deje implementado esto en el ejemplo en Github (https://github.com/paveliz/ClassesVarsValsyNullsEnKotlin), es la siguiente:

if( ! parametro.isNullOrEmpty() ) {

Java tiene un .isEmpty() pero si lo usan, la operación continuará dando NullPointerException. Pero Kotlin tiene un isNullOrEmpty() que realmente nos soluciona el tema de poder operar con nuestra variable siempre y cuando tenga algo y no sea nula.

En mi próximo post, continuaré con la introducción a nuevos elementos de este lenguaje.