# Android/Gradle amb exemples

En aquest capítol parlarem sobre la funció que realitza Gradle en Android Studio veient uns quants exemples del seu funcionament.
NOTA: els exemples han estat realitzats amb Android Studio 1.3.1, Build Tools 23.0.1, API Android 23 i Gradle 2.4

## Introducció a Gradle

Gradle és un sistema de compilació similar a Maven i Ant, amb la diferència que funciona amb múltiples llenguatges de programació com poden ser C++, Java i Android entre d'altres. Té la capacitat d'integrar-se sense problemes amb diferents entorns de desenvolupament (Netbeans, Eclipse, Android Studio...), mecanismes de controls de versions (Git, GitHub...) i sistemes operatius (Debian, Ubuntu, Android...), cosa que el converteix en una eina molt flexible.

## Gradle Wrapper

La característica més potent de Gradle és l'anomenat Gradle Wrapper. El wrapper es tracta d'un script que, en ser executat, descarrega automàticament la darrera versió de Gradle i compila amb ella el nostre projecte. Això dóna una gran seguretat a l'hora de desenvolupar de manera col·laborativa, on cadascú pot tenir un compilador diferent, garantint-nos que el compilador que s'utilitzarà serà el mateix per tothom.

### Instal·lació

El Gradle wrapper ve instal·lat automàticament amb l'Android Studio, però es pot instal·lar manualment si tenim ja tenim Gradle a l'ordinador, mitjançant la comanda 'gradle wrapper' al terminal.
* gradle wrapper --gradle-version 2.0
Podem especificar tant una versió (que es buscarà als repositoris oficials), com una URL que contingui una versió vàlida del gradle.

### Configuració i modificació

Si no configurem cap wrapper, el nostre projecte usarà el gradle que tinguem a la nostre màquina, fet que pot generar incongruències en intentar compilar en ordinadors externs al que s'ha utilitzat per crear el projecte. Per configurar el wrapper al nostre projecte, haurem de modificar el fitxer build.gradle i afegir-hi un tros de codi semblant a aquest:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
Un cop configurat, el projecte només usarà la versió especificada. Si la màquina no la té, la descarregarà, i si la té la utilitzarà directament.

## Fitxers de compilació

Centrant-nos en l'àmbit d'Android Studio, tenim dos fitxers de compilació. Un és per compilar el que és comú a tot el projecte i conté el següent:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
L'altre és per configurar el mòdul de la app en si i és semblant a aquest:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
El fitxer creat automàticament presenta les parts bàsiques que té qualsevol fitxer de compilació de Gradle:

### Versions d'eines de desenvolupament

Defineix quina eina de desenvolupament (SDK), i quina versió de compilador exacta estem fent servir en la nostra aplicació.

### Característiques - defaultConfig

Indica la ID de l'aplicació, i diferent informació sobre l'aplicació, com ara:
* Mínima Versió d'Android compatible.
* Versió d'Android predeterminada per l'aplicació
* Versió i número de revisió de l'aplicació.

### Definició de compilacions - buildTypes

El camp buildTypes pot ser utilitzat per diferenciar múltiples tipus de compilació (mode text, mode debug, versió per distribució, etc.). Els tipus de compilació incorporen una opció que pot millorar l'eficiència o la seguretat del codi: minifyEnabled. Quan aquesta opció està activada, es posa en marxa una eina d'Android coneguda com a ProGuard, que optimitza i redueix el codi, i també permet ofuscar el codi per afegir-li un punt de seguretat.

### Dependències

En aquesta part del codi, s' afegeixen totes les eines externes i les biblioteques necessàries que hàgim de fer servir per compilar el projecte d' Android. En concret aquí s'afegeixen les eines que permeten, al compilar l'aplicació, que sigui compatible amb les diferents versions del sistema operatiu, i els recursos compartits que usa Android en la majoria d'aplicacions (disseny de menús, Material design).

### Definició de flavors

També es poden definir altres parts disponibles a un arxiu de compilació, com ara la definició de flavors (diferents versions de l' aplicació, que explicarem més endavant), que afegeixen més potència al Gradle.
ProductFlavor és una característica molt potent disponible al connector Gradle Android que ens permet gestionar diferents "flavors" d'una aplicació.
Això és útil quan es desitja la mateixa aplicació però amb diferents característiques (per exemple, pel flavor de la versió completa vs versió gratuïta).
D'aquesta manera hem de crear:
'app/src/full/java' i 'app/src/demo/java' paral·lela a app/src/main/java
I així:
Classes i recursos comuns conviuran en el paquet main/java on com a flavor classes i recursos específics viuen a cada carpeta d'origen específica al seu propi existent.

## Modificant el fitxer

A l'hora de modificar el fitxer de Gradle tenim dues opcions que són: canviar el codi directament de forma manual o canviar-ho a través del mode gràfic d'Android Studio. Totes dues són igual de vàlides, però cal conèixer els avantatges i inconvenients de cadascuna d'elles.

### Modificació manual

Els avantatges de modificar el codi manualment són:
* Canvis ràpids: en comptes d'haver de navegar per diferents pestanyes, modifiquem allò que volem directament
* Dependències: si volem utilitzar alguna dependència que no haguem instal·lat amb l'SDK, podem introduir-la de forma manual i Gradle s'encarrega d'obtenir-la
A continuació veiem els inconvenients que comporta:
* Poc intuïtiu: per usuaris poc familiaritzats a Gradle, pot ser difícil saber què estan modificant
* Més errors: relacionat amb el punt anterior, és possible que estem modificant alguna cosa de forma errònia sense adonar-nos

### Modificació gràfica

Veiem ara els avantatges d'aquest mètode:
* Més intuïtiu: per a usuaris poc familiaritzats amb Gradle, el fet de veure en mode gràfic quina part s'està canviant ajuda a entendre què s'està fent
* Menys errors: seleccionar les opcions que ens ofereix l'entorn gràfic ens assegura que els canvis no seran erronis
I també els inconvenients:
* Canvis lents: haver de seleccionar les opcions navegant a través del mode gràfic no és tan directe com fer-ho manualment
* Dependències: les dependències que podem seleccionar estan acotades a les que hagin estat instal·lades prèviament a l'SDK

### Taula comparativa

M = Millor P = Pitjor :
| Característica | Manual | Gràfica |
| Rapidesa | M | P |
| Intuïtiu | P | M |
| Dependències | M | P |
| Menys errors | P | M |

### Conclusions

Veient els avantatges i els inconvenients d'ambdós mètodes, podem concloure que els dos són bones opcions a l'hora de modificar el fitxer i que l'ús de l'un o de l'altre dependrà de les preferències i necessitats de l'usuari.

## Interfície gràfica

En aquest apartat ens centrarem en explicar els aspectes bàsics que conté la interfície gràfica d'Android Studio per poder modificar les diferents seccions del fitxer de Gradle. Per accedir a aquesta interfície, anem a File > Project Structure..., o utilitzem el shortcut de teclat Ctrl+Alt+Mayus+S, i seleccionem el mòdul a modificar. Fent això, ens apareixerà una interfície semblant a aquesta:
A continuació veurem els diferents apartats i els elements de cadascun d'ells que podem canviar:

### Properties

* Compile Sdk Version: versió de la API amb la que es compilarà el projecte
* Build Tools Version: versió de les eines de compilació que s'utilitzaran
* Library Repository: ruta on es van a buscar les biblioteques externes de l'aplicació
* Ignore Assets Pattern: indica els fitxers o extensions de fitxer a ignorar durant la compilació
* Incremental Dex: indica si el projecte es compila només si ha sofert canvis o no, serveix per evitar compilar molts cops el projecte
* Source / Target Compatibility: indica la versió de sintaxi de Java compatible amb el codi font del projecte

### Signing

Per tal de poder compilar l'aplicació en un àmbit que no sigui debug, necessitem una clau de signatura i una configuració que associï aquesta clau amb un tipus de compilació. El per què necessitem la signatura es pot veure clarament en el següent diagrama:
Els paràmetres que s'han de configurar a l'apartat Signing són els següents:
* Name: nom de la configuració de signatura
* Key Alias: àlies de la clau de signatura
* Key Password: contrasenya de la clau de signatura
* Store File: arxiu on guardar la clau
* Store Password: contrasenya per l'arxiu de la clau

#### Exemple de creació d'una clau i una configuració de signatura

Per crear la clau de signatura, utilitzarem l'assistent que proporciona Android Studio i que es pot trobar a Build > Generate Signed APK. Crearem una nova, així que seleccionem Create New... i omplim els camps que ens demanin.
Un cop creada, anem a l'apartat signing de Project Structure i creem una nova configuració omplint els paràmetres d'acord a la clau que hem creat prèviament.
Si tot és correcte, al nostre fitxer Gradle s'haurà afegit la següent informació:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
Més tard veurem com associar aquesta configuració al tipus de compilació que decidim.

### Flavors

L'Android Studio té la capacitat de definir diferents versions de la nostra aplicació, amb diferents funcionalitats (versió de prova, versió complerta, funcionalitats específiques...).
El flavor principal del nostre projecte porta el nom de defaultConfig. És un apartat del fitxer de compilació del Gradle que crea automàticament l'Android Studio, i sempre apareix, tot i que no es vulguin definir diferents versions.
Els flavors, tant el defaultConfig com els nous flavors que es puguin afegir, tenen uns atributs que defineixen les seves característiques bàsiques.
* Name: nom de la configuració
* Min Sdk Version: versió mínima de la API que serà compatible amb l'aplicació
* Application Id: identificador de l'aplicació
* Proguard File: afegeix un fitxer de regles extra del Proguard només pel flavor en concret.
* Signing Config: configuració de signatura utilitzada
* Target Sdk Version: versió de la API a la qual va destinada l'aplicació
* Test Instrumentation Runner: biblioteca que executa la versió de testing de l'aplicació
* Test Application Id: identificador de la versió de testing de l'aplicació
* Version Code: número de revisió de l'aplicació (si s'ha anat millorant o afegint funcionalitats).
* Version Name: àlies que pot tenir una versió o revisió de l'aplicació.
Per afegir un nou flavor tenim dues maneres: modificant el codi, o des de la interfície gràfica de l'Android Studio:

#### Afegir un nou flavor mitjançant el codi

Els nous flavors es defineixen al fitxer de compilació del Gradle. A diferència del defaultConfig, els nous flavors han d'anar a un nou apartat anomenat "productFlavors". Dintre d'aquest apartat podrem definir els flavors extra que necessitem, i que tindran la mateixa estructura que el flavor principal. Un cop creat un flavor amb els mínims atributs, hauria de quedar un codi semblant a aquest exemple:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No

#### Afegir un flavor mitjançant una interfície gràfica

En aquest cas ens ajudarem del propi Android Studio per crear un flavor:
* Accedirem a la configuració del nostre projecte: File > Project Structure...
* Seleccionarem el nostre mòdul de l'aplicació i accedirem a la pestanya "Flavors".
* Cliquem el símbol "+", i afegim les característiques bàsiques que vulguem pel nostre flavor.
Això generarà la part de codi corresponent a l'apartat productFlavors del nostre arxiu del Gradle. Un cop fet això, haurem d'afegir els recursos al nostre flavor. Un cop generat, necessitarem afegir una ruta on s'emmagatzemarà tota la informació respectiva al flavor i els recursos necessaris.

#### Addició de recursos a un flavor (versions antigues d'Android Studio)

Un flavor acabat de crear no conté res per si mateix, així que li hem d'assignar un directori i crearem una nova Activity que es convertirà en la nostra nova APK derivada de la principal.
Començarem per afegir els directoris:
* Accedim a la visualització dels fitxers del nostre projecte.
* Expandim el directori "app".
* Botó dret sobre el directori "src" que haurà aparegut > New > Directory i li donem el nom del nostre flavor.
* Fem el mateix procediment dins de la nostre nova carpeta per crear els nous directoris java, res, res/layout i res/values.
Per acabar de fer funcional el flavor crearem i afegirem una activity lligada a aquest:
* En la visualització del projecte, cliquem botó dret al mòdul app > New > Activity.
* Escollim el tipus de plantilla que necessitem (usualment Blank Activity).
* Configurem la activitat com necessitem i finalitzem la creació.
* Accedim al directori java dins de la carpeta creada pel flavor.
* Cliquem botó dret > New > package.
* Anomenem el paquet amb el nom de la Activity.
* Movem la Activity a dins del paquet acabat de crear, i al pop-up que surt, marquem Refactor i acceptem.

#### Addició de recursos a un flavor (versions recents d'Android Studio)

* En la visualització del projecte, cliquem botó dret al mòdul app > New > Activity.
* Escollim el tipus de plantilla que necessitem (usualment Blank Activity).
* Configurem la activitat com necessitem i marquem el nostre flavor al camp Target Source Set.
En les noves versions d' Android Studio, el programa s'ocupa d'afegir els directoris, recursos i configuracions al moment de crear la activity, definint el destí (target).

### Build types

Aquí es defineixen els tipus de compilació i opcions que es poden realitzar. Per defecte trobem les de release i debug. Debug és la que s'utilitza per defecte mentre estem desenvolupant el codi i ens permet comprovar possibles errors i executar la nostra app en un emulador o en un dispositiu connectat per USB gràcies a la signatura per defecte que utilitza. En canvi, release s'utilitza per compilar quan es considera que la app està llesta per distribuir i no té una clau per defecte (veure Signing).
Un cop configurat un build type i un flavor, Android Studio crea el que es coneix com a Build Variant, que aplica les configuracions de versió mínima de la app, versió de target, etc. del flavor i les opcions de debug, optimització, etc. especificades al build type. Per cada flavor i build type especificat, Android Studio crea un Build Variant de la següent manera:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
A l'hora de compilar i executar la app, hem d'especificar que volem utilitzar un Build Variant o altre a l'apartat Build Variants d'Android Studio, al camp Build Variant del mòdul que desenvolupem. Un cop assignat, quan gradle compila i executa el projecte es crea un arxiu .apk indicant el tipus de compilació utilitzat.
Els paràmetres que podem configurar en aquest apartat són:
* Name: nom del tipus de compilació
* Debuggable: indica si el tipus de compilació es pot debugar o no
* Jni Debuggable: indica o afegeix l'opció de debugar el component JNI (Java Native Interface).
* Signing Config: configuració de signatura utilitzada
* Renderscript Debuggable: debug orientat al Renderscript, un framework per aplicacions amb treball paral·lelitzable i d'alt rendiment.
* Renderscript Optim Level: nivells d'optimització pel RenderScript.
* Minify Enabled: indica si es vol optimitzar i reduir el codi
* Pseudo Locales Enabled: activar opció d'utilitzar variacions mínimes de locales (idiomes) complets.
* Proguard File: afegeix un fitxer de regles pel mòdul que optimitza i redueix el codi (No reduir certes classes o variables, etc.).
* Application Id Suffix: nom que s'afegeix a la ID d'aplicació per distingir quin tipus de compilació hem fet (debug, release...).
* Version Name Suffix: nom que s'afegeix al nom de la versió per distingir quin tipus de compilació hem fet (debug, release...).
* Zip Align Enabled: activar mòdul que optimitza el codi alineant els bits que el formen, per millorar l'accés a les dades.

#### Exemple de creació d'un build type associant-li una configuració de signatura

Per aquest exemple crearem un build type debugable i amb l'opció de optimitzat habilitada. A l'apartat Build Types afegim un de nou prement la creu verda, li donem un nom, escollim true als camps Debuggable i Minify Enabled i escollim l'opció de Signing Config que haguem creat anteriorment. Premem OK i el fitxer Gradle quedarà modificat de la següent manera:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No

### Dependències

Es mostren les dependències que s'han afegit. Es poden afegir o treure dependències amb els botons de + i - que apareixen a la banda dreta de la interfície. Hi ha tres tipus de dependències:
* Biblioteca: utilitzem una biblioteca pròpia o externa per afegir funcionalitats
* Fitxer: afegim un directori on hem implementat una sèrie de funcionalitats que ens poden ser útils per a la nostra aplicació
* Mòdul: podem utilitzar funcionalitats d'un altre mòdul del projecte que haguem creat prèviament

## Exemples de modificació

A continuació mostrarem diversos exemples pas a pas per modificar les diferents parts del fitxer. Prendrem com a base el fitxer de compilació de l'apartat 2 d'aquest capítol i farem les modificacions amb la interfície gràfica.

### Canvi de la versió del compilador sdk

A l'apartat Properties, canviem la versió 23 per la versió 19 del compilador (es pot escollir qualsevol altre versió sempre que l'haguem instal·lat amb el gestor d'APIs del sdk) en el camp Compile Sdk Version i premem OK. En cas que la versió que hi hagi triada com a Target Sdk Version sigui superior a la del compilador, Android Studio ens avisarà del fet i haurem de canviar-ho per a què la compilació no doni errors. En aquest cas haurem d'anar a l'apartat Flavors i triar una versió de target adient per a la versió del compilador triada.
* Per canviar el compilador: Project Structure... > Properties > Compile Sdk Version > triar la versió > OK
* Per canviar la versió de target: Project Structure... > Flavors > Target Sdk Version > triar la versió > OK
El fitxer quedarà modificat de la següent manera:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
NOTA: no utilitzar la darrera versió d'Android en el compilador fa que s'apliquin modes de compatibilitat que poden afectar negativament a la compilació del projecte. Per això es recomana utilitzar la darrera versió del compilador i modificar només la versió de target de l'aplicació.
Modificant correctament les opcions, el codi resultant al fitxer serà el següent:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No

### Canvi de la versió mínima de l'aplicació

Si volem que la nostra aplicació sigui, o no, compatible a versions d'Android anteriors a la darrera, hem d'escollir quina serà la versió mínima de la API que podrà executar l'app. Per canviar això, haurem d'anar a l'apartat Flavors i triar una opció a la casella de Min Sdk Version. En el nostre cas, canviarem la versió de la 19 a la 23, és a dir, només la farem compatible per la darrera versió.
* Per canviar la versió mínima: Project Structure... > Flavors > Min Sdk Version > triar la versió > OK
El fitxer quedarà modificat de la següent manera:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No

### Afegir una nou tipus de compilació

Si a més de tenir els tipus debug i release volem afegir un tipus més de compilació, haurem d'anar a l'apartat Build Types i polsar la creu verda. En aquest cas hem fet un build type d'exemple que serà debugable i minificat i l'anomenarem nouBuildType.
* Per afegir un nou tipus de compilació: Project Structure... > Build Types > Creu verda > omplir les caselles > OK
El fitxer quedarà modificat de la següent manera:
* Link al repositori: Pàgina principal d'Android
* Anotacions: Revisat
* Vegeu també: No
Per a poder utilitzar aquest nou tipus de compilació, l'haurem de seleccionar en l'apartat Build Variants d'Android Studio.

### Diferents buildTypes i diferents flavors

Tenint d'exemple l'anterior cas amb diferents buildTypes, i afegint diferents flavors tenim una combinació de diferents compilacions per cada flavor, ja que els buildTypes es poden aplicar a cada un d'ells. En el cas dels dos fragments de codi d'exemple tindriem dos buildTypes (release i nouBuildType) i dos flavors (flavor i demoflavor). Les diferents possibilitats de compilació de flavors ens queden així:
* flavor-release
* flavor-nouBuildType
* demoflavor-release
* demoflavor-nouBuildType
D'aquesta manera tenim dues aplicacions (variant del programa inicial i versió de demostració) que podem compilar en la versió de release (codi compilat sense escriure informació pel desenvolupador, ofuscat i escurçat amb l'ús de Proguard) i en la versió de desenvolupament.

## Referències

* ↑ «Apache Maven». Apache, 24-09-2015. [Consulta: 8 octubre 2015].
* ↑ «Apache Ant». Apache, 07-03-2015. [Consulta: 8 octubre 2015].
* ↑ «Java Native Interface» (en castellà). [Consulta: 24/10/2015].