Artículos etiquetados con:android
Cómo compilar aplicaciones Android con Jenkins

En tiempos de desarrollo de software mediante metodologías ágiles, Scrum e integración continua, donde todos los miembros de un equipo integran su código frecuentemente y pueden realizar varias subidas al día dependiendo de las tareas a desarrollar, resulta imprescindible el uso de herramientas que permitan conocer en todo momento el estado del producto, las diferentes versiones y el estado en que se encuentra.

Cada vez que se realiza una subida de código al repositorio, se realiza una integración que compila el código fuente y verifica que se ha realizado correctamente, obteniendo un ejecutable de la aplicación. Para este proceso, en SDOS nos hemos decantado por el uso de Jenkins, un software gratuito y Open Source escrito en Java y está basado en el proyecto Hudson.

 

¿POR QUÉ JENKINS?

Este sistema soporta herramientas de control de versiones como SVN o GIT y puede ejecutar proyectos basados en Ant y Maven, Gradle, etc. Además, al ser un proyecto Open Source, es el más utilizado por los desarrolladores, contando con una gran comunidad de desarrollo y soporte.

Pero Jenkins no es sólo una herramienta para el equipo de desarrollo, también sirve al equipo de QA: del mismo modo que posibilita la ejecución de test automáticos o incluso el uso de Sonarqube, justo después de cada compilación permite comprobar la calidad de la subida.

 

¿CÓMO USAR JENKINS CON ANDROID?

En el desarrollo Android, Jenkins puede servirnos para generar un .apk cada vez que realicemos una subida de código al repositorio, guardándola en un servidor FTP donde tendremos un listado de todas las versiones generadas.

En este post os contamos cómo completar todo el proceso. ¡Empezamos!

 

1. CREAR UN PROYECTO EN JENKINS

En primer lugar, creamos un nuevo Job en Jenkins.

Paso 1 para compilar un .apk en Jenkins

A continuación, seleccionamos un nuevo proyecto Freestyle para poder configurarlo según nuestras necesidades. Escribimos un nombre y hacemos clic en OK.

Paso 2 para compilar un .apk en Jenkins

 

2. CONFIGURAR LAS SECCIONES DEL JOB

GENERAL

En esta sección definiremos lo siguiente:

  • Proyect name y description. Es recomendable dar un nombre intuitivo al proyecto y una descripción concreta para saber qué Job estamos ejecutando:

Paso 3 para compilar un .apk en Jenkins

  • Cuándo se descargan los builds antiguos. Es importante definir un número máximo de build a guardar ya que no queremos sobrecargar la máquina ni llenar de ejecuciones nuestro Job. Como recomendación, nos quedaremos con las 10 últimas ejecuciones realizadas. Si por necesidad del proyecto necesitamos que sean más, podría aumentarse el número, pero debería ser sólo en casos puntuales.

Paso 4 para compilar un .apk en Jenkins

  • Parámetros para ejecutar el proyecto. En la parte general también definiremos los parámetros necesarios para ejecutar un Job. Para añadirlos tenemos que hacer clic en This project is parameterized y seleccionar un Choice Parameter. Los parámetros para la compilación de una app de Android serán los siguientes:
    • Type. Por defecto en Android siempre aparecen dos tipos, debug y release, pero pueden añadirse tipos personalizados. En nuestro caso añadiremos: Release, Preproduction y Debug.
    • Flavors. Un flavor define una versión customizada de la aplicación. Esto nos permite definir diferentes personalizaciones de la aplicación dependiendo de la variante que necesitemos. Por ejemplo, podríamos tener un flavor para una demo de la aplicación y otro con la aplicación completa de pago.
    • Git Parameter. Definiremos como parámetro la rama que queremos del repositorio concreto. Tendremos que definir un valor por defecto para las ejecuciones automáticas. Si tenemos muchas ramas en un mismo repositorio, podemos hacer un filtro por nombre de rama como, por ejemplo, .*_rc.* (todas las ramas que incluyen _rc, release candidate).

Paso 5 para compilar un .apk en Jenkins

Paso 6 para compilar un .apk en Jenkins

 

Puedes encontrar más información sobre los parámetros en este enlace.

 

SOURCE CODE MANAGEMENT

En esta sección definiremos el tipo de repositorio que queremos usar, en nuestro caso será Git.

Una vez que seleccionamos la opción de Git tenemos que añadir:

  • URL del repositorio. Dónde está guardado el código del proyecto.
  • Credenciales. Usaremos en usuario git previamente añadido en Jenkins.
  • Branch. Especificaremos la rama específica del proyecto que usaremos. Como ya la hemos elegido una con el parámetro Git Parameter, le pasamos el valor de ese parámetro con $Branch.

Paso 7 para compilar un .apk en Jenkins

 

BUILD TRIGGERS

En esta sección definiremos el tipo de activador que necesitamos para ejecutar el build. Si no añadimos ninguno, sólo se ejecutará cuando nosotros lo forcemos. Desde aquí también podemos:

  • Realizar una ejecución remota desde un script.
  • Realizar la ejecución de forma periódica, por ejemplo cada noche a las 00:00.
  • Realizar una ejecución cuando se produzca un push o un new merge request en el repositorio.

Por ahora lo dejaremos por defecto y lo ejecutaremos manualmente.

 

BUILD ENVIROMENT

En esta sección definiremos dos opciones:

  1. Borrar la carpeta del workspace antes de cada ejecución (para realizar una ejecución limpia).
  2. Añadir el timestamp a los logs para tener más información.

Paso 8 para compilar un .apk en Jenkins

 

BUILD

En la sección del Build añadiremos un Execute shell para ejecutar los siguientes comandos:

Paso 9 para compilar un .apk en Jenkins

  • chmod +x gradlew: da permisos de ejecución al fichero gradlew por si no los tiene (por defecto ya los tiene).
  • ./gradlew: ejecuta el fichero gradlew en la máquina donde está Jenkins que es un Linux (¡cuidado con este fichero!).
  • assemble: es la orden para compilar una aplicación Android.
  • $Flavor: flavour elegido para la ejecución. Ponemos $ para que se sustituya el valor del parámetro por el seleccionado del desplegable flavor en la sección general.
  • $Type: type elegido para la ejecución. Ponemos $ para que se sustituya el valor del parámetro por el seleccionado del desplegable type en la sección general.

 

POST-BUILD ACTIONS

Desde esta sección realizaremos principalmente tres acciones:

  • Guardar el artefacto generado. Guardaremos todos los ficheros .apk generados en la compilación del proyecto. Por defecto lo guardaremos en: **/*.apk

Paso 10 para compilar un .apk en Jenkins

  • Enviaremos el fichero .apk dentro de la carpeta /apks/ a un servidor FTP. En nuestro caso, tenemos un servidor llamado NAS1 en el que guardaremos el apk generado en una carpeta ya creada dentro del servidor.Nota: para configurar la conexión con un servidor FTP debemos ir a Manage Jenkins > Configure Jenkins > Publish over FTP, y añadir los datos correspondientes a nuestro servidor.

Paso 11 para compilar un .apk en Jenkins

  • Enviar correo cada vez que termine un Build utilizando la acción post-build Editable Email Notification. La configuración que tendremos será la siguiente:

Paso 12 para compilar un .apk en Jenkins

 

Puedes copiar el contenido del mensaje por defecto de este HTML:

Default Subject

[JENKINS- ${JOB_NAME} ] Result of Build $BUILD_NUMBER ${JOB_NAME} Project.

Default Content

<html>
 
<p> Hello. </p>
 
<p>This mail is auto-generated as part of the Jenkins execution of the project <b>${JOB_NAME}</b> </p>
 
<h2> BUILD DETAILS: </h2>
 
<p>
       <b>Project Name:</b> ${JOB_NAME} <br>
       <b>Build URL:</b> ${BUILD_URL} <br>
       <b> Build Number: </b> ${BUILD_NUMBER} <br>
       <b>Build Status: </b> ${BUILD_STATUS} <br>
       <b>Type: </b> $Type <br>
       <b>Flavor: </b> $Flavor <br>
       <b>Branch: </b> $Branch <br>
       <b>Download APK: </b> ${BUILD_URL}/lastSuccessfulBuild/artifact/apks/ <br>
       <b>Log: </b> The log file is attached into this e-mail. <br>
       <b>Log URL: </b> ${BUILD_URL}${JOB_NAME}/lastBuild/console <br>
       <b>Changes: </b> ${CHANGES, format="List of changes: <li><ul>[%a] %m </ul><ul> [Date:] %d </ul> <ul> [Revision:] %r </ul></li> <br>"} <br>
</p>
 
<p> Thank you & Regards. </p>
 
</html>

 

Esta template es genérica para cualquier proyecto ya que usa las siguientes variables:

  • ${JOB_NAME}. Nombre del Job en el Jenkins.
  • ${BUILD_URL}. URL exacta del Job.
  • ${BUILD_NUMBER}. Número de Build ejecutado.
  • ${BUILD_STATUS}. Estado en el que ha finalizado el Build.
  • $Type. Tipo seleccionado al ejecutar el Build.
  • $Flavor. Flavor seleccionado al ejecutar el Build.
  • $Branch. Branch seleccionada al ejecutar el Build, si no se ha elegido ninguna aparece el nombre de la branch por defecto definida.
  • ${CHANGES}. Muestra los cambios realizados en el commit que ha activado el Build.
    • %a: autor del commit.
    • %m: mensaje del commit.
    • %d: fecha del commit.
    • %r: número de commit.

 

Esto dará lugar a un email como el que se muestra a continuación. Obtenemos así el .apk generado de forma sencilla.

Paso 13 para compilar un .apk en Jenkins

 

Sin lugar a dudas, en los últimos años Jenkins se ha convertido en una herramienta indispensable en el desarrollo de software ágil ya que, además de automatizar el proceso de producción de artefactos, garantiza la calidad en cada uno de ellos tanto para el cliente como para el propio equipo.


Android loves Kotlin: todo sobre el nuevo lenguaje de programación oficial

El pasado mes de mayo se celebró la edición anual de Google I/O, el evento donde la multinacional presenta las primicias que estarán a disposición de los usuarios de la gran G a corto y medio plazo, y también las novedades para los desarrolladores de las diferentes tecnologías relacionadas con su ecosistema.

Para Android, se presentaron características de la futura versión del sistema operativo, Android O: la nueva versión de la librería support, instant apps, las nuevas librerías para dar soporte a las arquitecturas de aplicaciones. Sin embargo, para mí y para muchos desarrolladores más, el anuncio más llamativo de todos fue la apuesta oficial por Kotlin como lenguaje de desarrollo Android.

¿Qué significa esto? Pues que a partir de la próxima versión 3.0 de Android Studio, podremos desarrollar aplicaciones para Android usando este lenguaje de programación, totalmente integrado por el IDE. Pero entremos un poco en materia.

 

¿QUÉ ES KOTLIN?

Kotlin es un lenguaje de programación de tipado estático que corre sobre la JVM que ha sido desarrollado por JetBrains, responsables de IntelliJ, IDE en el que se basa Android Studio (¡menuda casualidad!).

Aunque lleva fraguándose desde el año 2011, en febrero de 2016 se lanzó su primera versión estable 1.0 y este pasado marzo ya se actualizó a 1.1. Nació con la idea de sustituir a Java pero siendo totalmente interoperable con él y todo su ecosistema (para facilitar así la migración).

 

¿QUÉ APORTA KOTLIN QUE NO NOS DA JAVA?

Para dar una muestra de las bondades de Kotlin frente a Java, me voy a apoyar en las cuatro características que se mencionan en el libro “Kotlin for Android Developers” de Antonio Leiva, uno de los mayores referentes dentro de la comunidad Android y uno de los máximos promulgadores del nuevo lenguaje oficial de desarrollo.

  1. Expresividad
  2. Seguridad frente a nulos
  3. Funciones de extensión
  4. Programación funcional

 

1. EXPRESIVIDAD

Si queremos declarar una clase completa en Java tenemos que definir los getter, setter, toString, hashCode y equals. Por ejemplo, si definimos la clase “Dog”, tendríamos la siguiente clase Java:

public class Dog {
    
    private Long id;
    private String name;
    private String owner;
    private String breed;
 
    public Dog(Long id, String name, String owner, String breed) {
        this.id = id;
        this.name = name;
        this.owner = owner;
        this.breed = breed;
    }
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getOwner() {
        return owner;
    }
 
    public void setOwner(String owner) {
        this.owner = owner;
    }
 
    public String getBreed() {
        return breed;
    }
 
    public void setBreed(String breed) {
        this.breed = breed;
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        Dog dog = (Dog) o;
 
        if (id != null ? !id.equals(dog.id) : dog.id != null) return false;
        if (name != null ? !name.equals(dog.name) : dog.name != null) return false;
        if (owner != null ? !owner.equals(dog.owner) : dog.owner != null) return false;
        return breed != null ? breed.equals(dog.breed) : dog.breed == null;
 
    }
 
    @Override
    public int hashCode() {
        int result = id != null ? id.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (owner != null ? owner.hashCode() : 0);
        result = 31 * result + (breed != null ? breed.hashCode() : 0);
        return result;
    }
 
    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", owner='" + owner + '\'' +
                ", breed='" + breed + '\'' +
                '}';
    }
}

 

Como vemos, tenemos muchísimo código repetitivo (como casi todo en Java) para definir una clase. Sin embargo, todo eso lo podemos hacer en Kotlin de una forma muchísimo más sencilla.

data class Dog(var id: Long, var name: String, var owner: String, var breed: String)

 

Esto es sólo un ejemplo de que con mucho menos código podemos hacer muchas más cosas en Kotlin que en Java, y de una forma muy clara y legible.

 

2. SEGURIDAD FRENTE A NULOS

Cuando desarrollamos en Java, muchísimo código es defensivo. Esto supone que tenemos que comprobar continuamente cuándo algún objeto es nulo si no queremos encontrarnos con el típico error en tiempo de ejecución NPI. Sólo los tipos nativos no son nulos.

Dog dog = null;
Log.println(Log.INFO, "TEST", dog.getName());
#Este código se puede compilar, pero produce un NPI en tiempo de ejecución

 

Kotlin, sin embargo, como muchos otros lenguajes modernos, es seguro frente a nulos. Es decir, tenemos que especificar explícitamente cuándo un objeto puede ser nulo.

val dog1: Dog = Dog(lL, “Toby”, “Javi”, “Galgo”)
var dog2: Dog? = null
 
#Me permite compilar
dog1.print()
 
#No me permite compilar al no comprobar que es nulo
dog2.print()
 
#Con el operador ? si me deja hacerlo
dog2?.print()
 
#O como en Java
 
if(dog2 != null){
	dog2.print() 
}
#Ahora si compila, al estar dentro de un bloque donde se ha comprobado que no es nulo.
 
#Podemos usar el operador Elvis para dar un valor cuando la variable es nula
var name = dog2.name ?: “Desconocido”

 

3. FUNCIONES DE EXTENSIÓN

Con Kotlin podemos añadir nuevas funciones a cualquier clase de Java o Android con las funciones de extensión, que se entienden y son mucho más intuitivas que las típicas clases de utilidades que todo programador ha usado alguna vez.

Podemos, por ejemplo, añadir un método a un fragment para que muestre un toast de la siguiente forma:

fun Fragment.toast(message: CharSequence, duration: Int = Toast.LENGHT_SHORT){
	Toast.makeText(activity, message, duration).show
}
 
#Y lo podemos usar dentro de un fragment directamente:
toast.dog1.name

 

4. PROGRAMACIÓN FUNCIONAL

Realmente, con Java 8 podemos usar programación funcional con lambdas, pero éstas están bastante limitadas con respecto a todo el potencial que nos aporta Kotlin.

Dentro de un fragment con un TextView podemos implementar el típico onClickListener con una lambda de la siguiente forma:

textView.setOnClickListener {toast.dog2?.name}

 

EL FUTURO DE Y CON KOTLIN

Esto es sólo una pequeña muestra de todo el potencial que tiene este joven pero maduro lenguaje de programación. Podría contar más de las funciones sobre colecciones, properties, delegados, corrutinas, smartcast, etc., pero aún es un mundo por descubrir.

Actualmente, el equipo de desarrollo de Jetbrains está trabajando en Kotlin/Native, lo que significa que, en un futuro próximo, Kotlin podrá ser lenguaje para el desarrollo de aplicaciones iOS. Tendremos así la posibilidad de reutilizar código fuente con Android (¡qué bien suena!), sistemas embebidos o IoT (Arduino, por ejemplo), BigData, servicios, desarrollo de videojuegos, etc. En fin, el futuro.


Nuestro resumen de #Exfest16

Cáceres acogió este fin de semana la segunda edición de ExFest, evento en el que se han cita desarrolladores y reconocidos ponentes para compartir conocimientos y tendencias sobre las tecnologías de Google, tanto móvil como web.

A la cita acudió parte de nuestro equipo Android, quienes destacan el alto nivel de las conferencias y el valor aportado en materia de arquitecturas de aplicaciones, testing y resilencia de los sistemas operativos. Pudieron conocer también de primera mano la experiencia de aplicaciones como Twitter, donde se puso de manifiesto la importancia de la constante evolución de las apps móviles.

Desde SDOS queremos felicitar a GDG Cáceres por la organización. Ya esperamos con ganas la edición de 2017.


SDOS en el MaterialFest

Miembros de los equipos de movilidad y diseño de SDOS acudieron el pasado sábado a MaterialFest, la primera edición de un encuentro destinado a desarrolladores y diseñadores del sistema Android, un evento pensado para profesionales que “realmente hacen los productos hablando desde la experiencia”.

Con una asistencia de 350 profesionales y speakers internacionales de startups de éxito, la jornada se desarrolló entre charlas y tracks: uno enfocado en diseño digital (con charlas sobre tipografía, Material Design, iconografía y guías de estilo), otro enfocado en desarrollo Android (charlas sobre frontend en Android, animaciones y programación funcional) y otros eventos paralelos sobre UX y mesas redondas.

En definitiva, un evento para que, como apunta uno de nuestros desarrolladores, SDOS pueda ser más Material y Android si cabe.


Uso de cookies

Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continúas navegando estas dando tu consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pincha el enlace para obtener más información.

ACEPTAR