LATÍN BÁSICO CON EVOLUCIONES AL ESPAÑOL por Paco Bombín García
TRABAJO FIN DE GRADO Evoluciones y refactorizaciones de...
Transcript of TRABAJO FIN DE GRADO Evoluciones y refactorizaciones de...
Graduado en Ingeniería Informática
Universidad Politécnica de Madrid
Escuela Técnica Superior deIngenieros Informáticos
TRABAJO FIN DE GRADO
Evoluciones y refactorizaciones de una aplicación Androidpara alfabetización digital
Autor: Álvaro Pérez Filoche
Director: Ángel Herranz
MADRID, ENERO DE 2020
Al equipo de TEDECO por dignificar nuestra profesión
Índice general
Resumen IX
Abstract XI
1. Introducción 1
1.1. TechPeopleCare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2. Motivación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3. Objetivos del TFG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Historias de usuario 5
2.1. Tipos de usuario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1. Instalador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2. Usuario no alfabetizado . . . . . . . . . . . . . . . . . . . . . . . . 7
3. Diseño de Experiencia de Usuario 11
3.1. Navegación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2. Splash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3. Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4. CourseList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.5. Course . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
I
3.6. Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4. Arquitectura de la aplicación 21
4.1. Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.1.1. Actividades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.1.2. Vistas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.1.3. Fragmentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2. Patrón Arquitectónico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.1. Clean Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.2. Modelo-Vista-Presentador . . . . . . . . . . . . . . . . . . . . . . . 27
4.3. Entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.4. Arquitectura de TechPeopleCare Android App . . . . . . . . . . . . . . . . . 30
4.4.1. Estructura general por archivos . . . . . . . . . . . . . . . . . . . . . 30
4.4.2. Estructura por paquetes . . . . . . . . . . . . . . . . . . . . . . . . . 31
5. Implementación 37
5.1. Bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.1.1. ExoPlayer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.1.2. ObjectBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.1.3. Dagger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.1.4. ButterKnife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.1.5. Retrofit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2. Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.3. Análisis de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6. Conclusiones y trabajo futuro 47
6.1. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
6.2. Trabajo futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
II
Bibliografía 49
III
IV
Índice de figuras
3.1. Navegación implementada con Navigation Component . . . . . . . . . . . . 12
3.2. Pantalla de Splash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3. Lógica, vista y controlador en Splash . . . . . . . . . . . . . . . . . . . . . . 13
3.4. Pantalla de Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5. Lógica, vista y controlador en Code . . . . . . . . . . . . . . . . . . . . . . 15
3.6. Pantalla de CourseList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.7. Diagrama de clases de CourseList . . . . . . . . . . . . . . . . . . . . . . . 16
3.8. Pantalla de Course . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.9. Diagrama de clases de Course . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.10. Pantalla de Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.11. Diagrama de clases de Player . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.1. Diagrama del ciclo de vida de una actividad . . . . . . . . . . . . . . . . . . 23
4.2. Arquitectura Clean Code. Autor del diagrama: Robert C. Martin . . . . . . . 27
4.3. Interacción entre los componentes del Modelo-Vista-Presentador . . . . . . . 28
4.4. Patrón MVP en TechPeopleCare Android App. . . . . . . . . . . . . . . . . 29
4.5. Entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.6. Estructura por paquetes de TechPeopleCare App . . . . . . . . . . . . . . . . 31
4.7. Diagrama de clases del paquete api . . . . . . . . . . . . . . . . . . . . . . . 32
V
4.8. Diagrama de clases del paquete dal . . . . . . . . . . . . . . . . . . . . . . . 33
4.9. Diagrama de clases del paquete domain . . . . . . . . . . . . . . . . . . . . 34
4.10. Diagrama de clases del paquete injection . . . . . . . . . . . . . . . . . . . . 35
4.11. Diagrama de clases del paquete logic . . . . . . . . . . . . . . . . . . . . . . 35
4.12. Diagrama de clases del paquete mvp . . . . . . . . . . . . . . . . . . . . . . 36
5.1. Funcionalidad de descarga de medios en ExoPlayer . . . . . . . . . . . . . . 38
5.2. Implementación de un repositorio con ObjectBox . . . . . . . . . . . . . . . 41
5.3. Relaciones de dependencia entre las distintas clases de la app . . . . . . . . . 43
VI
Índice de cuadros
4.1. Relación entre el ciclo de vida de un proceso y el estado de una actividad (ver
https://developer.android.com/guide/components/activities/activity-lifecycle) 24
4.2. Tabla de relación entre los símbolos de plantuml y su significado relativo a la
visibilidad de métodos y atributos. . . . . . . . . . . . . . . . . . . . . . . . 32
VII
VIII
Resumen
Con el súbito avance tecnológico de los últimos 30 años, propulsados por el advenimiento
de Internet y los teléfonos inteligentes, han aumentado los servicios al alcance de los ciudada-
nos. Entre estos servicios, cabe destacar los servicios orientados a la salud. Desde la búsqueda
de un médico o un centro sanitario, pasando por la descarga de dípticos para recetas electró-
nicas o la posibilidad de pedir citas sanitarias; todo esto ya se puede realizar a través de un
teléfono inteligente o un ordenador.
Con el fin de ayudar a aquellas personas que no saben utilizar estos dispositivos a que
puedan acceder a estos servicios, surge TechPeopleCare Android App. Esta aplicación permi-
te descargar cursos de alfabetización digital y reproducir sus vídeos de una manera sencilla e
intuitiva, facilitando el aprendizaje individualizado sin la necesidad de profesores presencia-
les.
El trabajo realizado para Evoluciones y refactorizaciones de una aplicación Android paraalfabetización digital ha consistido en primer lugar en el estudio de la aplicación TechPeo-pleCare Android App, desarrollada por Ángel Herranz. Esto ha supuesto, no solo un entendi-
miento de la plataforma Android, sino también de conceptos y filosofías como Clean Code,
Ley de Demeter, inyección de dependencias o el Modelo-Vista-Presentador. También fue ne-
cesaria la comprensión del funcionamiento de la base de datos utilizada (ObjectBox), el gestor
de descargas y reproductor de vídeo (ExoVideoCache), así como otras bibliotecas utilizadas
como Dagger, ButterKnife y RetroFit.
Una vez comprendida la arquitectura y el funcionamiento de la app, todo el trabajo pos-
terior se centró en realizar refactorizaciones, resolver bugs, documentar el código de la apli-
cación, corregir avisos y potenciales errores informados por el analizador estático de código
y la implementación de nuevas funcionalidades; como por ejemplo la adición de una pantalla
para el ingreso de un código de instalación, la incorporación de un botón de rebobinado du-
rante la reproducción de un vídeo o la mejora en la gestión de los estados de descarga de los
vídeos.
IX
X
Abstract
With the sudden technological advancement made in the last 30 years, driven by the
coming of the Internet and smartphones, more services than ever are available to the general
public. Some of the most important are the health related services. From searching for a
doctor to a hospital, to the download of electronic prescriptions or making an appointment
with your doctor; all of this is possible to do through the screen of a smartphone or a computer.
In order to help those who are not able to use these kind of devices, TechPeopleCareAndroid App was developed. This app allows its user to download digital literacy courses
and play its videos in a simple and intuitive manner, enabling an individualized learning
process without the need of assisting an instructor-led classroom.
The work done for Evoluciones y refactorizaciones de una aplicación Android para alfa-betización digital has consisted firstly in the study of the TechPeopleCare Android App, de-
veloped by Ángel Herranz. This implies, not only an understanding of the Android platform,
but also of concepts and philosophies such as Clean Code, Demeter Law, dependency injec-
tion or the Model-View-Presenter. It was also necessary to understand the inner workings of
the database used (ObjectBox), the download manager and video player (ExoVideoCache), as
well as other libraries used such as Dagger, ButterKnife and RetroFit.
Once the architecture and functioning of the app were understood, all subsequent work
focused on the resolution of bugs, the documentation of the code of the application, fixing
warnings produced by the static code analyzer and the implementation of new features; such
as the addition of a screen for entry of an installation code, the inclusion of a rewind button
during the playback of a video or the improvement of the video’s download state.
XI
XII
1
Introducción
Este trabajo consistirá en el estudio, mejora y refactorización de una aplicación Android
orientada a la alfabetización digital. Esta aplicación pertenece a un proyecto llevado a cabo
por la empresa social TechPeopleCare (https://www.techpeople.care), cuyos objetivos se
pueden encontrar en dicha Web.
La aplicación que concierne a este trabajo está orientada a la alfabetización digital, asis-
tiendo al usuario en el aprendizaje desde los conceptos más básicos como el uso del ratón y el
teclado, hasta al acceso a servicios en línea como el de búsqueda de farmacias cercanas, bús-
queda de médicos o la cumplimentación de un formulario que permita pedir cita en un centro
de atención primaria. De esta manera, permite acceder a los servicios de salud a aquellos ciu-
dadanos en riesgo de exclusión en ámbitos tecnológicos como pueden ser aquellos que viven
en zonas rurales o personas de la tercera edad. Asimismo, la aplicación también permite la
elección de los cursos en distintos idiomas, facilitando así el acceso a los servicios de salud a
personas que no entiendan castellano. El hecho de realizarse a través de una aplicación móvil
permite al usuario ser autodidacta, con una enseñanza individualizada que le permita avanzar
a la velocidad que requiera y en cualquier momento.
1
1 Introducción
TechPeopleCare Android App tiene como funcionalidad principal la descarga de material
videográfico y su reproducción. Estos vídeos, pertenecientes a cursos didácticos para la al-
fabetización digital, podrán ser reproducidos en un reproductor adaptado a esta aplicación,
con un interfaz sencillo que facilite su uso para un analfabeto digital1. Además, en el caso de
que se requiera, los cursos descargados a través de TechPeopleCare Android App podrán ser
actualizados cómodamente.
1.1 TechPeopleCare
La empresa social TechPeopleCare surge del Grupo de Tecnología para el Desarrollo y
la Cooperación (TEDECO) de la Universidad Politécnica de Madrid. Su misión es impactar
de forma drástica en la reducción de la brecha digital, ayudando a la consecución de los
objetivos sociales de las instituciones gubernamentales y sin ánimo de lucro y colaborando
con el éxito profesional y la responsabilidad social corporativa de las empresas privadas.
TechPeopleCare participa en el programa internacional EIT Health, cuyo objetivo es aportar
soluciones de I+D en el ámbito de la salud. Esta aplicación en concreto pertenece al programa
de e-Health inclusion through ICT training, al cual está asociado el Servicio Madrileño de
Salud (SERMAS).
Esta empresa social ofrece servicios de auditoría, consultoría, diseño de cursos y manteni-
miento de materiales. Actualmente, los cursos de alfabetización digital que se ofrecen desde
TechPeopleCare son orientados al aprendizaje del uso de un ordenador y de un dispositivo
móvil.
1.2 Motivación
La aplicación TechPeopleCare surge de la necesidad de crear un entorno que facilite el
proceso de alfabetización digital de una persona sin la necesidad de un profesor presencial.
Para llevar esto a cabo, no es suficiente con guardar vídeos en un dispositivo tablet, ya que
esto acarrea los siguientes inconvenientes:
No permite adaptar el interfaz a las necesidades concretas del usuario.
Dificulta el proceso de actualización de los cursos.
1Utilizamos el término para referirnos a personas sin “habilidad para localizar, analizar, organizar, entender
y evaluar información utilizando tecnología digital”, artículo Alfabetización digital en la Wikipedia: https:
//es.wikipedia.org/wiki/Alfabetismo_digital
2
1.3 Objetivos del TFG
Imposibilita añadir nuevas funcionalidades que puedan ayudar al usuario a interactuar
con la aplicación.
El proceso de descarga de un curso puede ser excesivamente laborioso, y más aún en si-
tuaciones en las que se han de instalar los cursos de alfabetización digital en numerosos
dispositivos.
Los reproductores de vídeo tienen interfaces complejos, con cambios de contexto y
excesivos botones.
Con el fin de solucionar estos problemas se desarrolla la aplicación de TechPeopleCareAndroid App. Esta proporciona un reproductor de vídeo con un interfaz sencillo e intuitivo,
además de facilitar la descarga de cursos y su actualización, todo ello adaptando el interfaz
al idioma correspondiente al curso instalado.
1.3 Objetivos del TFG
La aplicación de TechPeopleCare Android App ha de evolucionar en función de las obser-
vaciones que realice el equipo de TechPeopleCare en las pruebas que se realicen en entornos
reales y respondiendo a las necesidades y cambios que requiera el usuario.
Tras un estudio preliminar del estado inicial en el que se encuentre la aplicación, será
necesario un proceso de refactorización en el que se revise la arquitectura con el fin de ase-
gurarse que se ajusta a principios como el principio de menor conocimiento, el principio de
inversión de control de dependencias o la filosofía Clean Code, además de adherirse a un
patrón arquitectónico de tipo Modelo-Vista-Presentador y llevar a cabo un control apropiado
del Lifecycle. Una vez hecho esto, y tras analizar el código haciendo uso de herramientas co-
mo el analizador de código de Android Studio e implementando las correcciones necesarias,
se procederá a desarrollar las nuevas funcionalidades o correcciones que el equipo de Tech-PeopleCare considere necesarias en función de sus observaciones en las pruebas realizadas
en entornos reales. En el caso de añadir nuevas funcionalidades, siempre tendrán que reali-
zarse teniendo en cuenta a los usuarios finales de esta aplicación, los cuales en su mayoría no
estarán familiarizados con el uso de una tableta Android ni con una pantalla táctil. Además,
estas nuevas funcionalidades deberán regirse por los principios y las estructuras menciona-
das anteriormente en el periodo de refactorización. Finalmente, se ampliará y completará la
documentación perteneciente a esta aplicación.
3
1 Introducción
4
2Historias de usuario
En este capítulo, en primer lugar se describirán los tipos de usuarios, siendo estos el
usuario instalador y el usuario no alfabetizado. Finalmente se expondrán las historias de
usuario con sus correspondientes casos de uso.
Todo esto se hará siguiendo prácticas de los procesos ágiles, no solo por su velocidad,
flexibilidad y eficiencia; sino también por poner al usuario final como prioridad y al cual
siempre se ha de tener en cuenta durante desarrollo.
2.1 Tipos de usuario
Usuario instalador: El usuario instalador será el administrador del dispositivo dónde
se impartan los cursos de alfabetización digital. Tendrá la labor de descargar la aplica-
ción, introducir el código proporcionado por TechPeopleCare e instalar el curso que sea
conveniente, asegurándose de que el dispositivo tiene conexión a internet para poder
descargar los vídeos. Una vez estén todos los vídeos del curso descargados, el usuario
no alfabetizado podrá hacer uso de la aplicación sin la necesidad de tener el dispositivo
conectado a internet.
Usuario no alfabetizado (o analfabeto digital): El usuario no alfabetizado será quien
navegue a través de la lista de vídeos del curso y quien reproducirá aquellos vídeos
5
2 Historias de usuario
que crea conveniente, con el fin de progresar en su aprendizaje en el ámbito de la
alfabetización digital.
2.1.1 Instalador
Como instalador, quiero instalar un curso de alfabetización digital
El instalador instala la aplicación en el dispositivo.
El instalador introduce el código de instalación proporcionado por TechPeople-Care.
El sistema valida el código.
Si hay más de un curso, el sistema ofrece elegir entre varios cursos al instalador.
El instalador elige el curso a instalar.
El sistema guarda la selección del instalador.
Como instalador, quiero conocer el estado de las descargas de los ví-deos
El instalador selecciona un curso para instalar.
El sistema guarda la selección del instalador.
El sistema comienza a descargar los vídeos del curso seleccionado.
El sistema informa en la pantalla del estado de descarga de cada vídeo.
El sistema notifica al instalador si alguna descarga fue errónea.
El sistema habilita la reproducción de los vídeos ya descargados.
6
2.1 Tipos de usuario
Como instalador, quiero ser capaz de actualizar un curso
El instalador abre la aplicación.
El sistema muestra el curso instalado con la lista de vídeos.
El instalador hace clic cinco veces sobre el título del curso.
El sistema actualiza la lista de vídeos.
El sistema informa al instalador de que ha de reiniciar la aplicación y muestra
un botón para reiniciar.
El instalador pulsa el botón de reiniciar.
El sistema reinicia la aplicación y muestra el curso ya actualizado.
2.1.2 Usuario no alfabetizado
Como usuario no alfabetizado, quiero que el interfaz de la aplicación semuestre en un idioma que comprenda
El usuario no alfabetizado abre la aplicación.
El sistema muestra el interfaz en el idioma del curso instalado.
Como usuario no alfabetizado, quiero ser capaz de elegir el vídeo queconsidere oportuno, de modo que pueda aprender a mi ritmo
El usuario no alfabetizado selecciona un vídeo para reproducir entre la lista de
vídeos de un curso.
El sistema comienza la reproducción del vídeo seleccionado.
7
2 Historias de usuario
Como usuario no alfabetizado, quiero poder pausar un vídeo, para asípoder asimilar mejor los conceptos
El usuario no alfabetizado selecciona un vídeo para reproducir entre la lista de
vídeos de un curso.
El sistema comienza la reproducción del vídeo seleccionado y muestra en la
pantalla un botón de pausa.
El usuario no alfabetizado pulsa el botón de pausa.
El sistema pausa el vídeo y muestra en la pantalla un botón de reanudación.
El usuario no alfabetizado pulsa el botón de reanudación.
El sistema continúa reproduciendo el vídeo a partir del punto en el que quedó
pausado.
Como usuario no alfabetizado, quiero poder rebobinar un vídeo, para asípoder repasar conceptos
El usuario no alfabetizado selecciona un vídeo para reproducir entre la lista de
vídeos de un curso.
El sistema comienza la reproducción del vídeo seleccionado y muestra en la
pantalla un botón de rebobinar.
El usuario no alfabetizado pulsa el botón de rebobinar.
El sistema retrocede en el vídeo y continúa la reproducción a partir de ese punto.
8
2.1 Tipos de usuario
Como usuario no alfabetizado, quiero ser capaz de reproducir el siguien-te vídeo de un curso una vez haya terminado el vídeo que estaba repro-duciendo
El usuario no alfabetizado selecciona un vídeo para reproducir entre la lista de
vídeos de un curso.
El sistema comienza la reproducción del vídeo seleccionado.
El sistema, una vez terminado el vídeo, muestra en la pantalla un botón para
reproducir el siguiente vídeo.
El usuario no alfabetizado pulsa el botón de reproducción del siguiente vídeo.
El sistema comienza a reproducir el siguiente vídeo de la lista del curso.
Como usuario no alfabetizado, quiero poder retroceder a la lista de ví-deos si he seleccionado el vídeo equivocado
El usuario no alfabetizado selecciona un vídeo para reproducir entre la lista de
vídeos de un curso.
El sistema comienza la reproducción del vídeo seleccionado y muestra en la
pantalla un botón para volver a la lista de vídeos.
El usuario no alfabetizado pulsa el botón de volver.
El sistema vuelve a la pantalla con la lista de vídeos del curso.
9
2 Historias de usuario
10
3
Diseño de Experiencia deUsuario
Para diseñar la UI de la aplicación, se ha optado por seguir el sistema de diseño MaterialDesign de Android (https://material.io). Material Design define un estilo de diseño y unos
principios que permiten a las aplicaciones de Android tener un diseño en armonía con el resto
del sistema, formando así una experiencia de usuario uniforme dentro de la plataforma.
Material Design se caracteriza por dar un papel principal a sombras, bordes, superficies y
colores. Con esta filosofía se trata de conseguir que haya un sentido de orden y jerarquía muy
marcados, algo primordial a la hora de diseñar un interfaz destinado a analfabetos digitales.
Debido a que la aplicación va dirigida a analfabetos digitales, se ha optado por minimizar
el uso de animaciones y transiciones ya que, a pesar de ser algo característico de MaterialDesign, puede dificultar la interacción de los usuarios con la aplicación. Aprovechando los
componentes de Material Design como los botones, cajas de texto o ventanas de alerta, junto
con el uso de un color uniforme (azul) asociado a TechPeopleCare, se ha conseguido un
diseño agradable a la vista y en armonía con el ecosistema de Android.
11
3 Diseño de Experiencia de Usuario
3.1 Navegación
A continuación se va a exponer cómo se desarrolla la navegación dentro de la aplicación,
por secciones, analizando cada pantalla por separado. Como se puede observar en la figura
3.1, existen distintas vías para llegar a las distintas pantallas pero con el fin de demostrar
el funcionamiento de la aplicación al completo, se va a seguir un orden equivalente al que
experimentaría un usuario instalador que acaba de instalar la aplicación.
Figura 3.1: Navegación implementada con Navigation Component
Cada una de las pantallas va a ser explicada en los siguientes apartados. Para cada apar-
tado se mostrará:
Captura de pantalla de la pantalla en cuestión.
Diagrama1 de decisión con cierta parte de la lógica en dicha pantalla.
Diagrama con el controlador (sufijo Fragment) y sus métodos y la vista (sufijo View) y
sus métodos.
1Advertimos al lector que los diagramas en este capítulo son meramente ilustrativos y no siguen formalmente
la sintaxis y semántica de UML.
12
3.2 Splash
3.2 Splash
Figura 3.2: Pantalla de Splash
Esta será la primera pantalla con la que se encuentre el usuario. Aparece durante 1.500
ms con un indicador circular para asegurar al usuario que la aplicación se encuentra activa y
muestra el logo de TechPeopleCare con un fondo del color azul característico de la marca.
Con esta pantalla se pretende mostrar al usuario que está iniciando la aplicación de Tech-PeopleCare mientras se realizan operaciones en el fragmento para determinar cuál será la
próxima pantalla a navegar. En el caso de que un curso ya esté instalado, se navegará a la
pantalla de Course (3.5); sino se tendrá que comprobar si el instalador ya introdujo un có-
digo de instalación previamente. En el caso de que ya hubiera introducido correctamente un
código de instalación, la navegación será hacia CourseList (3.4); en caso contrario será hacia
Code (3.3).
Figura 3.3: Lógica, vista y controlador en Splash
13
3 Diseño de Experiencia de Usuario
3.3 Code
Figura 3.4: Pantalla de Code
En la pantalla de Code se le insta al instalador (2.1) a introducir un código de instalación.
En el caso de no querer introducir un código en ese momento, se muestra un botón de cerrar
para salir de la aplicación. Este código a introducir, el cual será proporcionado por TechPeo-pleCare, irá asociado a uno o varios cursos. Si el usuario introduce el código correctamente,
la siguiente pantalla será la de Course si el código estaba asociado a un solo curso, o la lista
de cursos en el caso de que el código correspondiera a más de un curso.
Este mecanismo, en el cual se asocian códigos a cursos, fue implantado con vistas a una
futura publicación de la aplicación en la Play Store de Google, que es la tienda de aplica-
ciones más utilizada en Android. Una vez esté publicada la aplicación en la Play Store, los
instaladores podrán actualizar la aplicación sin necesidad de volver a descargar todos los ví-
deos, que es un proceso largo debido a la cantidad y tamaño de los vídeos. Gracias a esto,
también será más fácil que las nuevas funcionalidades acaben llegando a los usuarios, cuyas
necesidades marcarán qué nuevas funcionalidades o cambios se añadan en la aplicación.
14
3.4 CourseList
Figura 3.5: Lógica, vista y controlador en Code
3.4 CourseList
Figura 3.6: Pantalla de CourseList
El instalador llegará a esta pantalla cuando introduzca un código que esté asociado a más
de un curso. Aquí podrá elegir entre una lista de cursos para instalar. Una vez seleccione
el curso que crea conveniente, se pasará a la pantalla de Course, el idioma de la aplicación
pasará a coincidir con el idioma del curso y comenzará la descarga de vídeos. En el caso
de que el instalador no quiera todavía elegir un curso para instalar, en la esquina superior
15
3 Diseño de Experiencia de Usuario
derecha de la pantalla se muestra un botón que cierra la aplicación.
En esta pantalla se pueden apreciar algunas características de Material Design, como son
el uso de bordes redondeados y las sombras en las tarjetas de los cursos. Estas últimas per-
miten dar una impresión de profundidad y jerarquía, ayudando a interpretar mejor el interfaz
a simple vista.
Figura 3.7: Diagrama de clases de CourseList
3.5 Course
Figura 3.8: Pantalla de Course
Una vez llegue el instalador a esta pantalla, ya no tendrá que volver a realizar los pasos
anteriores, ya que del Splash pasará directamente a Course con la lista de vídeos. Esto permite
que el analfabeto digital pueda abrir la aplicación y elegir directamente el vídeo que quiera
ver, sin necesidad de mayores complicaciones.
16
3.5 Course
Cuando llegue el instalador por primera vez a esta pantalla, se comenzarán a descargar
los vídeos del curso. En la captura de pantalla mostrada previamente se pueden apreciar tres
estados de descarga:
Descargado: El vídeo se ha descargado al completo y se muestra un botón para poder
ver el vídeo en cuestión.
Descargando: El vídeo se encuentra en proceso de descarga. Su porcentaje se irá ac-
tualizando en la pantalla cada tres segundos.
En espera: El vídeo está en la cola de descarga. Esto se puede deber a que se ha llegado
ya al número máximo de descargas activas paralelas o a que no hay conexión de red.
Además de estos tres estados, que son los más comunes, pueden aparecer otros dos estados:
∗ Error: Ha habido un error en la descarga. Esto provocará que se muestre una notifica-
ción informando al usuario sobre qué descarga ha fallado.
∗ Desconocido: Se muestra cuando la aplicación todavía no ha tenido tiempo de procesar
cuál es el estado de la descarga.
En el caso de que el instalador o el usuario quieran salir de la aplicación, se muestra un
botón que cierra la aplicación en la esquina superior derecha de la pantalla.
Figura 3.9: Diagrama de clases de Course
17
3 Diseño de Experiencia de Usuario
3.6 Player
Figura 3.10: Pantalla de Player
Por último, la pantalla de Player será la pantalla en la cual se reproduzcan los vídeos.
Aparecerá cuando el usuario haga clic en el botón de ver, que aparece en la tarjeta de un
vídeo ya descargado en la pantalla de CourseList (3.4). Una vez en esta pantalla, el vídeo
comienza a reproducirse desde el principio y aparecen tres botones por pantalla:
Botón izquierdo (Vídeos): Retrocede a la lista de vídeos.
Botón central:
• Pausar: Se muestra durante la reproducción del vídeo. Pausa el vídeo.
• Continuar: Se muestra mientras el vídeo está pausado. Reanuda la reproducción.
Botón derecho:
• Rebobinar: Se muestra durante la reproducción del vídeo. Retrocede diez segun-
dos en el vídeo.
• Siguiente: Se muestra una vez el vídeo ha finalizado, siempre y cuando no sea el
último vídeo del curso. Reproduce el siguiente vídeo en el curso.
• Salir: Se muestra una vez se ha terminado de reproducir el último vídeo del curso.
Cierra la aplicación
18
3.6 Player
Figura 3.11: Diagrama de clases de Player
19
3 Diseño de Experiencia de Usuario
20
4Arquitectura de la aplicación
En este apartado se describe en primer lugar la plataforma de desarrollo elegida, los fac-
tores que influyeron en la elección y las principales clases utilizadas en esta plataforma.
Posteriormente se explicarán qué filosofías se han seguido a la hora de escribir código y
de estructurar la arquitectura de la aplicación. Finalmente se mostrará la arquitectura de la
aplicación TechPeopleCare App.
4.1 Android
A la hora de elegir plataforma de desarrollo para esta aplicación, Android se presenta
como una elección evidente; no solo por tener la mayor cuota de mercado (y por lo tanto
mayores potenciales usuarios), sino por ser el sistema operativo por antonomasia en disposi-
tivos móviles de gama baja/media. Este factor es trascendental, ya que esta aplicación va a
ser utilizada en instituciones o entornos con reducido poder adquisitivo. Además de esto, el
hecho de que sea un sistema operativo de código abierto y tenga un interfaz simple e intuitivo,
cimenta la elección de Android como plataforma de desarrollo. Con el fin de poder entender
cómo está estructurada una aplicación Android, en el siguiente apartado se van a explicar
algunas clases clave:
21
4 Arquitectura de la aplicación
4.1.1 Actividades
Las actividades son un componente crucial de las aplicaciones Android. Una actividad de
Android es capaz de manejar el interfaz gráfico y gestionar la interacción de un usuario con
este interfaz, siendo las actividades las que proporcionan al sistema la ventana con la que va
a interactuar el usuario.
En Android solo puede haber una actividad en primer plano y para administrar esto existe
el ciclo de vida, que está formado por las siguientes etapas:
onCreate(): Llamado nada más lanzarse una actividad. En él se inicializan las princi-
pales funciones como asignar listeners e inflar widgets.
onStart(): Llamado tras onCreate(), marca el momento previo a que la actividad vaya
a ser visible al usuario.
onResume(): Llamado después de onStart() cuando la actividad está en primer plano y
es visible al usuario.
onPause(): Llamado cuando la actividad deja de estar en primer plano o pierde el foco.
onStop(): Llamado cuando la actividad no es visible, ya sea porque esta actividad ha
sido destruida o porque otra actividad ha pasado al primer plano.
onRestart(): Llamado después de onStop() en el caso de que el usuario haya decidido
volver a poner la actividad en primer plano
onDestroy(): Llamado cuando el usuario decide dar por finalizada su interacción con
la actividad.
22
4.1 Android
Actividad lanzada
onCreate()
onStart()
onResume()
Actividad en uso
onPause()
onStop()
onDestroy()
onRestart()
Proceso terminado
Actividad cerrada
Otra actividad pasa
al primer plano
La actividad ha dejado de ser visible
La actividad es cerrada por el usuario o el sistema
La activi-
dad pasa al
primer plano
prioridad más alta → mayor memoria
El usuario navega
a la actividad
La actividad
pasa al
primer plano
Figura 4.1: Diagrama del ciclo de vida de una actividad
Una aplicación, al tener varias actividades en distintos estados simultáneamente, consu-
me RAM que el sistema puede necesitar; por lo que a la hora de liberar RAM, el sistema
terminará procesos (en los que se están ejecutando las actividades) en función del estado en
el que esté el proceso.
En la siguiente tabla se muestra la correlación entre el estado de un proceso, el estado de
la actividad y la probabilidad de que el sistema termine el proceso.
23
4 Arquitectura de la aplicación
Probabilidad de ser terminado Estado del proceso Estado de la actividad
Baja En primer plano
onCreate
onStart
onResume
Media En el fondo (pierde el foco) onPause
Alta
En el fondo (no visible)
-
Vacío
onStop
-
onDestroy
Cuadro 4.1: Relación entre el ciclo de vida de un proceso y el estado de una actividad (ver
https://developer.android.com/guide/components/activities/activity-lifecycle)
4.1.2 Vistas
Las vistas son uno de los pilares de la creación del interfaz de usuario. Ocupan un área
rectangular de la pantalla y tienen como funciones manejar eventos (como el clic de un bo-
tón), dibujar el interfaz y gestionar los widgets. Para este proyecto los widgets utilizados han
sido las cajas de texto, los botones y las tarjetas de contenido. Para gestionar la interacción
con estos widgets, en las vistas se utilizan unos listeners que se encargarán de notificar a la
aplicación en el caso de que el usuario interactúe con un widget, como puede ser al pulsar un
botón.
A estas vistas hay asociado un fichero XML en el cual se establecen las propiedades de los
distintos elementos que aparecen en pantalla. Entre las propiedades que se pueden fijar sobre
estos elementos están su tamaño, si son visibles o no, su color o su posición en la pantalla.
4.1.3 Fragmentos
Los fragmentos son partes modulares de una actividad que los aloja. Tienen sus propios
eventos de entrada y ciclos de vida, aunque sus ciclos de vida están influenciados por el estado
de la actividad que los aloja. Los fragmentos surgen en Android 3.0 como una forma de dar
al desarrollador mayor flexibilidad a la hora de optimizar la experiencia de los usuarios en
dispositivos con pantallas de mayor tamaño.
En este proyecto los fragmentos se han utilizado para gestionar la parte lógica de las ope-
raciones mientras que las vistas se encargan de gestionar aquellas operaciones relacionadas
con el interfaz mostrado en la pantalla. El uso de fragmentos no ha sido mayor a uno por vis-
ta, ya que las pantallas no se han hecho complejas ni multifuncionales con el fin de facilitar
el uso de la aplicación para un usuario no alfabetizado.
24
4.2 Patrón Arquitectónico
4.2 Patrón Arquitectónico
4.2.1 Clean Code
Clean Code hace referencia a una guía de buenas prácticas a la hora de arquitecturar apli-
caciones orientadas a objeto. Dicha guía fue ideada por Robert C. Martin (también conocido
como Uncle Bob) y se puede encontra en su libro Clean Code [1]. Esta guía de buenas prác-
ticas busca que el código limpio sea legible, refactorizable, elegante y fácil de probar. Todo
esto no solo ayuda a que el código sea entendible, sino también a que sea fácil de cambiar y
de mantener para otros desarrolladores además del autor del código.
Algunas de las propuestas a destacar de esta filosofía en ámbitos generales son:
Reducir la complejidad al máximo posible.
Seguir las convenciones.
Los nombres han de ser descriptivos y sin prefijos ni abreviaturas.
Las funciones han de ser de tamaño reducido, de un solo propósito y con el menor
número de parámetros posible.
En lo que se refiere a la arquitectura, Clean Code establece que para que una arquitectura sea
limpia ha de ser:
Independiente de los frameworks, que han de servir como herramientas y no como
restricciones.
Independiente del interfaz de usuario, ya que permite cambiar éste sin afectar al resto
del sistema.
Independiente de la base de datos, por lo que no afectaría a nuestras reglas de negocio
cambiar de la base de datos actual, ObjectBox, a otra como SQL Server.
Independiente de cualquier entidad externa.
Testeable de manera que permita testar las reglas de negocio sin necesitar elementos
como la base de datos o el interfaz de usuario.
25
4 Arquitectura de la aplicación
Cabe destacar una de las directrices que más ha influido en la arquitectura de la aplicación: el
uso del Principio de Inversión de Dependencias. En palabras del propio Robert C. Martin
[2]:
Las clases de alto nivel no deberían depender de las clases de bajo nivel. Ambas debe-rían depender de las abstracciones.
Las abstracciones no deberían depender de los detalles. Los detalles deberían depen-der de las abstracciones.
En otras palabras, el Principio de Inversión de Dependencias indica que las clases de bajo
nivel han de depender de abstracciones y no de detalles concretos. Aplicar la inversión de
dependencias junto con la Ley de Demeter, que establece que una clase solo ha de conocer
sus dependencias directas, aporta los siguientes beneficios:
Permite reutilizar componentes debido a que las dependencias se pueden inyectar y
configurar externamente.
Facilita las pruebas unitarias gracias a que se pueden inyectar dependencias de prueba.
Simplifica los cambios en la implementación de objetos, ya que estos están desacopla-
dos y aislados.
26
4.2 Patrón Arquitectónico
La siguiente figura ilustra la arquitectura resultante de aplicar Clean Code. En ella se
representa la relación de dependencia entre las distintas areas software, de manera que las
dependencias solo pueden ir hacia el interior del círculo. Esto implica, por ejemplo, que
nada declarado en los casos de uso o en los adaptadores del interfaz pueda ser utilizado por
las entidades. De esta forma se evita que las reglas de negocio deban de ser alteradas por
cambios en el interfaz o en el framework.
Figura 4.2: Arquitectura Clean Code. Autor del diagrama: Robert C. Martin
Con el uso de inyección de dependencias a través de la librería Dagger (5.1.3) y aplicando
el Principio de Inversión de Dependencias a través de los interfaces de Java, se ha logrado
maximizar la reusabilidad, la mantenibilidad y la facilidad de testeo del código para este
proyecto.
4.2.2 Modelo-Vista-Presentador
El Modelo-Vista-Presentador [3], abreviado como MVP a partir de ahora, son una serie de
patrones arquitectónicos utilizados para construir interfaces de usuario. Este patrón permite
ahondar en la filosofía Clean Code mencionada en el capítulo anterior y está compuesto por
los siguientes componentes:
Modelo: Guarda el estado del sistema.
27
4 Arquitectura de la aplicación
Vista: Se encarga del input-output hacia y desde el usuario.
Presentador Encapsula la lógica funcional del sistema.
Desacoplar estos componentes lo máximo posible favorece que cualquiera de los compo-
nentes pueda ser cambiado sin afectar a los otros dos. Esto ayuda a seguir conceptos tan
importantes para el Clean Code como es la abstracción completa del interfaz de usuario. En
el siguiente diagrama se puede apreciar como interactúan estos tres componentes:
Figura 4.3: Interacción entre los componentes del Modelo-Vista-Presentador
En el MVP, la vista no sabe nada sobre el modelo y es el presentador el encargado de
obtener datos actualizados sobre el modelo para así interpretar si la vista ha de ser o no
actualizada. En el caso de que la vista tenga que ser actualizada, será el presentador quien
aplicará estos datos sobre la vista. Esto deja a la vista con dos únicas funciones: recibir el
input del usuario y renderizar los datos que el presentador le ha aplicado.
MVP en Android
No existe una descripción formal de MVP así que a la hora de llevarlo a cabo, existen
múltiples caminos. Dentro de la comunidad de desarrolladores de Android hay bastante con-
troversia al respecto de su aplicación. En este trabajo se han seguido las orientaciones del
desarrollador Vasily Zukanov (https://www.techyourchance.com). La principal directriz de
Zukanov es:
Activities in Android are not UI Elements
Para trasladar este concepto a nuestra arquitectura, y además aplicar los principios de
Clean Code, hemos elaborado el patrón que ilustra la figura 4.4 y que se explica a continua-
ción:
28
4.3 Entidades
Figura 4.4: Patrón MVP en TechPeopleCare Android App.
Existe una clase abstracta mvp.MvpView que nos permite abstraernos de todo lo rela-
cionado con las vistas de Android.
Por cada pantalla creamos un fragmento que hace las veces de Presenter y que interna-
mente mantiene referencias al modelo.
Cada vista concreta expone una abstracción de las posibles acciones del usuario en
forma de Listener: onActioni().
A su vez declara un interfaz de operaciones para ser actualizada: updatej().
El fragmento concreto por su parte, mantiene una referencia a la vista concreta en la
que se registra como Listener (setListener()).
E implementa cada una de las operaciones onActioni().
4.3 Entidades
En esta sección vamos a centrarnos en el modelo de datos de la aplicación, lo que en CleanCode se denominan entidades (Entities). El modelo de datos de la aplicación es bastante
sencillo y se ilustra en esta figura:
Los objetos que implementan la interfaz Repository son capaces de rescatar el curso
previamente instalado.
Un curso tiene múltiples vídeos. Su título es único.
29
4 Arquitectura de la aplicación
Figura 4.5: Entidades
Los objetos que implementan la interfaz VideoCache permiten descargar y almacenar
vídeos.
El aspecto más relevante de los vídeos es que su URI y la versión los identifica unívo-
camente.
4.4 Arquitectura de TechPeopleCare Android App
En esta sección se va a analizar brevemente la estructura general del proyecto. Esto se va
a explicar utilizando la estructura de la herramienta de desarrollo utilizada, Android Studio,
ya que es mucho más esclarecedora que la estructura estricta por archivos. Finalmente se va
a profundizar sobre la estructura por paquetes con las clases e interfaces de Java. Será en esta
sección donde se concentre el trabajo de desarrollo.
4.4.1 Estructura general por archivos
La estructura de archivos de proyecto en Android Studio está organizada por módulos, de
manera que los archivos más importantes sean fácilmente accesibles. Los directorios tienen
las siguientes funciones:
manifests: Contiene el AndroidManifest.xml que describe información fundamental
para la compilación, el sistema operativo y la Google Play Store.
java: Contiene el código fuente Java. Es aquí donde se concentra el trabajo de desarro-
llo y cuya explicación se encuentra en el apartado 4.4.2.
30
4.4 Arquitectura de TechPeopleCare Android App
res: Abarca todos los recursos no relacionados con el código fuente. Los recursos a
destacar en este directorio son: los archivos .XML de layouts, los strings para el in-
terfaz de usuario (con sus respectivas traducciones a inglés, español, árabe y francés)
y la estructura de navegación entre las distintas pantallas de la aplicación definida en
navigation_main.xml.
Gradle Scripts: Incluye los scripts de configuración para la compilación del proyecto
implementados en Gradle (https://gradle.org/features/). Esta herramienta de códi-
go abierto, incluída en Android Studio, permite automatizar el proceso de compilación
de código haciendo uso de scripts escritos en Apache Groovy. En ellos se han definido
aspectos como los directorios de donde obtener las librerías, las versiones de la aplica-
ción y su nivel de API de Android, el número máximo de descargas paralelas de vídeos
o las dependencias de la aplicación.
4.4.2 Estructura por paquetes
Figura 4.6: Estructura por paquetes de TechPeopleCare App
En lo que se refiere al paquete principal care.techpeople, podemos encontrar tres clases:
TechPeopleCareApp: Inicializa la caché y la base de datos.
MainActivity: Contiene la base de la actividad de Android.
VideoDownloadService: Extiende el servicio de descarga de medios ofrecido por Exopla-yer (5.1.1).
31
4 Arquitectura de la aplicación
Como aclaración, se muestra una tabla a modo de leyenda explicando el significado de los
símbolos utilizados en los diagramas de clase relacionados con la visibilidad de los atributos
y los métodos.
Cuadro 4.2: Tabla de relación entre los símbolos de plantuml y su significado relativo a la
visibilidad de métodos y atributos.
api
Figura 4.7: Diagrama de clases del paquete api
En este paquete se realizan las peticiones de get a la URL de TechPeopleCare a través
de Retrofit (5.1.5). Con el servicio generado por esta biblioteca, la lógica de obtención de
cursos (4.4.2) podrá generar peticiones de obtención de cursos a la API de TechPeopleCare.
En estas peticiones, una vez parseado el Json asociado al código introducido por el usuario,
se mapean a través del Mapper los objetos de Json a objetos de dominio (siendo estos objetos
a mapear los cursos y los vídeos).
32
4.4 Arquitectura de TechPeopleCare Android App
dal
Figura 4.8: Diagrama de clases del paquete dal
En este paquete, cuyas siglas responden a Capa de acceso a datos, podemos observar
que se encuentran tanto la base de datos de ObjectBox (5.1.2) como el gestor de descargas
de medios en la caché de Exoplayer (5.1.1). Además de esto, hay un Mapper utilizado para
transformar objetos de dominio a objetos de entidad, siendo estos últimos los que se guarden
en la base de datos.
33
4 Arquitectura de la aplicación
domain
Figura 4.9: Diagrama de clases del paquete domain
En el paquete domain será donde se defina la estructura de los objetos de dominio, sien-
do estos los vídeos y los cursos. En este paquete se encuentra también uno de los concep-
tos clave de este proyecto, los interfaces para la inversión de dependencias. Estos interfaces
(Repository para la base de datos y VideoCache para el gestor de descargas en caché) están
relacionados con las dependencias externas a la lógica de negocio (dominio) y permiten abs-
traer el núcleo de la aplicación de otros detalles de la implementación. Esto es esencial a la
hora de que sea un proyecto fácil de testar y de mantener, tal y como se explica en el capítulo
sobre CleanCode (4.2.1)
34
4.4 Arquitectura de TechPeopleCare Android App
injection
Figura 4.10: Diagrama de clases del paquete injec-
tion
En el paquete injection se encuen-
tran los métodos y anotaciones necesa-
rios para la implementación de la inyec-
ción de dependencias a través de Dag-
ger. Como se puede apreciar en este dia-
grama, la clase Provider provee las ins-
tancias de la base de datos (ObjectBox)
y el gestor de caché (ExoVideoCache)
a aquellas clases que dependen de
ellas (SplashFragment, CodeFragment,
CourseListFragment, CourseFragment y
VideoView). Para obtener más informa-
ción sobre cómo se ha realizado esta
implementación de la inyección de de-
pendencias a través de Dagger, consulte
el apartado: 5.1.3
logic
Figura 4.11: Diagrama de clases del paquete logic
35
4 Arquitectura de la aplicación
En logic se desempeñarán las labores de ejecución de hilos para llevar a cabo tareas de
forma asíncrona. Las tareas que se llevan a cabo son:
Obtención de cursos: con GetCoursesLogic se realizan consultas al servicio de la API
TechPeopleCare (gracias a Retrofit 5.1.5). Su resultado se comunicará con callbacks
a través de interfaces, gracias al uso de listeners por parte del fragmento que haya
realizado la petición.
Cambios en el locale de la aplicación: en esta lógica, utilizada al instalar un curso, se
cambiarán los ajustes relacionados con el idioma del interfaz de la aplicación y otros
aspectos como la orientación de los textos.
mvp
Figura 4.12: Diagrama de clases del paquete mvp
En este paquete se encuentran todos los fragmentos y vistas de la aplicación. Para obtener
más información sobre qué papel desempeña cada vista con su respectivo fragmento, consulte
el capítulo sobre Diseño de la Experiencia de Usuario (3)
36
5Implementación
En este apartado se exponen las bibliotecas utilizadas para implementar la aplicación
móvil y las herramientas utilizadas para su desarrollo.
5.1 Bibliotecas
Las funcionalidades de las bibliotecas del Android SDK (Software Development Kit) son
limitadas. Con el fin de suplir esta carencia de funcionalidades esenciales para el desarrollo
de esta aplicación móvil, se han recurrido a las siguientes bibliotecas:
ExoPlayer: Descarga y reproducción de medios
ObjectBox: Base de datos orientada a objetos
Dagger: Inyección de dependencias
ButterKnife: Reducción de código repetitivo
Retrofit: Cliente HTTP
37
5 Implementación
5.1.1 ExoPlayer
ExoPlayer es una biblioteca surgida de un proyecto de código abierto ajeno a la infra-
estructura de Android y cuyos componentes están construidos sobre la API MediaCodec,
lanzada en la versión 4.1 de Android (nivel de API 16). En este caso, la aplicación de Tech-
PeopleCare está desarrollada para tener soporte para dispositivos con una versión de Android
a partir de la 7.0, por lo que esto no será un inconveniente.
La biblioteca ExoPlayer tiene como unas de sus cualidades más importantes la capacidad
tanto de reproducción de medios, como de su descarga; siendo la descarga de vídeos una
funcionalidad vital para la aplicación, ya que posibilita la reproducción de los vídeos sin
la necesidad de estar permanentemente conectado a Internet (y las complicaciones que esto
conlleva si un alfabeto digital va a usar esta aplicación).
Descarga de vídeos
Figura 5.1: Funcionalidad de descarga de medios en ExoPlayer
(https://exoplayer.dev/downloading-media.html)
Tal y como se puede observar en la Figura 5.1, tenemos varios componentes a tener en
cuenta a la hora de realizar una descarga:
Código de la aplicación: Tras la selección de un curso por parte del usuario, la lista
de vídeos de este curso se recorrerá en un bucle para iniciar las descargas en la clase
ExoVideoCache a través del método download:
public void download(Video video) {
Uri contentUri = video.uri();
String contentId = cacheId(video);
String videoTitle = video.title();
byte[] appData = videoTitle.getBytes(StandardCharsets.UTF_8);
DownloadRequest downloadRequest =
38
5.1 Bibliotecas
new DownloadRequest(contentId,
DownloadRequest.TYPE_PROGRESSIVE,
contentUri,
Collections.emptyList(),
null,
appData);
DownloadService.sendAddDownload(mContext,
VideoDownloadService.class,
downloadRequest,
false);
}
Como se puede observar, en una descarga se transmite al DownloadService en un DownloadRequest
información como el URI del vídeo, su identificador único y el tipo de descarga a rea-
lizar, además de información útil para uso interno de la aplicación a través de appData,
donde se almacenará el título del vídeo.
DownloadManager: Permite la gestión de varias descargas, almacenar información sobre
el estado de éstas y empezar y detener descargas en función de requisitos como el de
no exceder un número determinado de descargas paralelas o el estado de la conexión
de red.
Tal y como indica la Figura 5.1, DownloadManager se encargará de leer datos a través
del HttpDataSourceFactory para escribirlos en la Cache. Esto, junto con la capacidad
de DownloadIndex de obtener el estado de las descargas, permite no solo el mero hecho
de iniciar una descarga; sino también de informar al usuario sobre el estado actual de
una descarga, así como de errores en la misma. En el caso que se produjera un error en
una descarga, se le comunicaría al usuario a través de una notificación de Android.
Reproducción de vídeos
ExoPlayer admite diversos formatos de vídeo como MP4, M4A, WAV, WebM o Matroska
(https://exoplayer.dev/supported-formats.html) pero en el caso de TechPeopleCare App,
todos los vídeos usarán de formato contenedor MP4, un formato con amplio soporte y que
permite la transmisión de flujos por Internet. La reproducción de un vídeo se realiza con una
transmisión de tipo progresivo, en la cual se crea un MediaSource que representa el vídeo a
reproducir y apunta a la URI de susodicho vídeo.
private void play(long position) {
// This is the MediaSource representing the media to be played.
MediaSource videoSource =
new ProgressiveMediaSource.Factory(mDataSourceFactory).createMediaSource(mVideo.uri());
39
5 Implementación
// Prepare the mSimpleExoPlayer with the source.
mSimpleExoPlayer.prepare(videoSource);
if (position > 0) {
mSimpleExoPlayer.seekTo(mSimpleExoPlayer.getCurrentWindowIndex(), position);
}
mButtonReplay.setVisibility(View.GONE);
mButtonNext.setVisibility(View.GONE);
mButtonExit.setVisibility(View.GONE);
mPlayerControlView.setVisibility(View.VISIBLE);
mSimpleExoPlayer.setPlayWhenReady(true);
}
Como se puede apreciar, la biblioteca de ExoPlayer facilita en gran medida la reproduc-
ción de un vídeo, dejando como única tarea pendiente para el programador la disposición de
los botones del interfaz del reproductor.
5.1.2 ObjectBox
ObjectBox es una base de datos orientada a objetos con soporte para Android (entre otras
plataformas) y que aboga por la simplicidad de su uso, la rapidez en sus operaciones y el
reducido impacto en el rendimiento (https://objectbox.io/mobile/). Este último punto es
clave ya que se prevé que el uso de esta aplicación sea sobre dispositivos con capacidad de
procesamiento reducida, por lo que la experiencia de usuarios con dispositivos Android de
gama baja se ha de tener en cuenta en todo momento.
Para el uso de esta biblioteca, que se puede obtener a través del repositorio de jcenter, es
necesario el entendimiento de varios conceptos:
Entidad1: Las clases anotadas con @Entity, definen el modelo físico del objeto a guar-
dar en la base de datos. Estas entidades han de tener un campo de tipo long, anotado
con @Id, necesario para uso interno de ObjectBox a la hora de realizar la indexación
de objetos. Además de esta anotación, para este proyecto también se ha utilizado la
anotación @Unique que impone que el valor del campo anotado con @Unique sea único.
1Aunque el nombre surge por la inspiración del término entidad en Clean Code o el desarrollo guiado por el
dominio (DDD de las siglas en inglés: Domain-Driven Design), no debemos pensar que con ObjectBox podemos
representar entidades realmente, más bien son objetos de la capa más externa de CleanCode.
40
5.1 Bibliotecas
Y más importante aún, la clase genérica ToMany, permite informar a ObjectBox de una
asociación de multiplicidad 1..∗ con otra clase.
A continuación, se presenta CourseEntity como ejemplo de entidad de ObjectBox, con
la anotación @Unique en title impidiendo así que haya dos objetos en la base de datos
con el mismo título, y con una propiedad de tipo ToMany que captura la asociación hasdel modelo de datos del apartado 4.3:
@Entity
public class CourseEntity {
@Id long id;
@Unique String title;
...
@Backlink(to = "courses")
ToMany<VideoEntity> videos;
}
Box: es una clase genérica capaz de almacenar objetos de un determinado tipo. En este
proyecto se utilizan objetos Box sobre tres clases anotadas con @Entity: Box<CourseEntity>,
Box<VideoEntity>, Box<ConfigEntity>.
Esta infraestructura queda completamente aislada del resto de la aplicación, utilizando
una inversión de dependencias y un objeto capaz de transformar entidades de ObjectBox y
entidades del modelo de datos conceptual. La siguiente figura muestra las clases más rele-
vantes para lograr este aislamiento2:
Figura 5.2: Implementación de un repositorio con ObjectBox
ObjectBoxRepository es capaz de devolver el curso instalado.
2Por simplicidad no se muestran todas las entidades involucradas pero creemos que es sencilla su deducción.
41
5 Implementación
Para ello accede a un objeto de la clase Box<CourseEntity> de la que extrae el curso
instalado (un objeto de la clase CourseEntity).
Y utiliza un Mapper para transformarlo en un objeto del dominio: Course.
El código cliente no sabe nada de ObjectBoxRepository ya que lo recibe como un objeto
Repository inyectado.
5.1.3 Dagger
La biblioteca Dagger, desarrollada por Google, facilita la creación y provisión de las de-
pendencias. No solo mejora el rendimiento y clarifica los posibles errores, sino que con el
uso de anotaciones se simplifica la implementación de la inyección de dependencias (con-
cepto desarrollado en 4.4). Esto facilita su entendimiento para futuros programadores que se
involucren con el desarrollo de la app gracias a la reducción de la ofuscación de código. Las
anotaciones que se han utilizado son las siguientes:
@Inject: Comunica a Dagger que una clase o campo participa en la inyección de
dependencias. El siguiente extracto de código muestra el uso de esta anotación en
CourseFragment, el cual depende de la base de datos (Repository) y de la caché del
gestor de descargas de vídeos (VideoCache):
public class CourseFragment
extends Fragment
implements CourseView.Listener,
VideoCache.Listener,
GetCoursesLogic.Listener
{
...
@Inject VideoCache mVideoCache;
@Inject Repository mRepository;
...
}
@Module: Los módulos son clases que proporcionan dependencias. De esta manera Dag-
ger sabe dónde encontrar las dependencias a la hora de satisfacerlas cuando se cons-
truyen las instancias de una clase. En nuestro caso solo la clase Provider tendrá esta
anotación.
@Provides: Esta anotación define qué métodos van a proporcionar las dependencias.
Más abajo, se ilustra como se utilizó esta anotación junto con @Module para permitir a
Dagger proporcionar las dependencias:
42
5.1 Bibliotecas
@Module
class Provider {
@Provides
Repository repository() { return ObjectBoxRepository.getInstance(); }
@Provides
VideoCache videoCache() { return ExoVideoCache.getInstance(); }
@Provides
ExoVideoCache exoVideoCache() { return ExoVideoCache.getInstance(); } }
@Component: Inyecta dependencias a cada uno de los campos y métodos anotados con
@Inject. A continuación se muestra cómo se utilizó esta anotación en el interfaz Injector:
@Component(modules = {Provider.class})
public interface Injector {
void inject(SplashFragment splashFragment);
void inject(CodeFragment codeFragment);
void inject(CourseListFragment courseListFragment);
void inject(CourseFragment courseFragment);
void inject(VideoView videoView);
}
Con el uso de todas estas anotaciones se logra establecer un sistema de inyección de
dependencias tal y como se representa en la siguiente figura, en la cual se puede apreciar el
papel central que juega el repositorio de ObjectBox mencionado en el punto anterior:
Figura 5.3: Relaciones de dependencia entre las distintas clases de la app
43
5 Implementación
5.1.4 ButterKnife
La biblioteca ButterKnife, desarrollada y mantenida por Jake Wharton, permite usar ano-
taciones para instanciar las vistas de una actividad o fragmento. Como aclaración, denotar
que el procesamiento de anotaciones es un mecanismo del compilador de Java que permite
escanear y procesar anotaciones durante el tiempo de compilación para generar nuevas clases
de Java.
Cuando se procesan anotaciones relacionadas a ButterKnife, esta biblioteca genera clases
de Java que, una vez realizada la llamada a ButterKnife.bind(this), serán utilizadas para
generar los constructores necesarios y efectuar la inyección de vistas. El uso de la anotación
@BindView en este proyecto ha permitido eliminar las repetitivas llamadas a findViewById,
dando lugar a código mucho más claro y elegante. A continuación se muestra un ejemplo de
inyección de vistas a través de ButterKnife, en este caso aplicado a CourseView:
@BindView(R.id.textView_header_title) protected TextView mTextViewHeaderTitle;
@BindView(R.id.progressBar_header) protected ProgressBar mProgressBar;
@BindView(R.id.recyclerView_videos) protected RecyclerView mRecyclerViewVideos;
@BindView(R.id.button_back) protected Button mButtonBack;
De esta manera se consiguen generar automáticamente atributos con su tipo correspon-
diente, como el atributo mButtonBack de tipo Button, y éstos quedan ya asociados al ID de la
vista.
5.1.5 Retrofit
Retrofit es un cliente HTTP para Android que permite transformar una API HTTP a un
interfaz de Java. Esta funcionalidad, unida a la capacidad de parsear los JSON que se en-
cuentran en el servidor de TechPeopleCare (gracias a la integración con la librería Jackson),
consigue recuperar los cursos asociados al código introducido por el usuario de la aplicación.
5.2 Javadoc
Javadoc es una herramienta de generación de documentación desarrollada por Oracle pa-
ra el lenguaje Java. Gracias a esta herramienta se puede generar documentación de API en
HTML a partir del código fuente en Java. Para este proyecto, se han documentado todas las
clases Java del proyecto con el fin de facilitar el mantenimiento de la aplicación y para per-
mitir que futuros desarrolladores de esta aplicación puedan entender el código rápidamente.
44
5.3 Análisis de código
A continuación se ofrece un ejemplo de comentario de Javadoc, en el cual se utilizan eti-
quetas de Javadoc @param y @return para definir los parámetros de un método y la devolución
del mismo respectivamente.
/**
* Gets a course entity saved in the course Box that matches a certain course title.
*
* @param courseTitle Title of the course to be searched.
* @return Course entity that matched the title given as a parameter.
*/
CourseEntity getCourseEntity(String courseTitle) {
CourseEntity courseEntity = null;
List<CourseEntity> courseEntities = mCourseBox.query().
equal(CourseEntity_.title, courseTitle).build().find();
if (courseEntities.size() > 0) {
courseEntity = courseEntities.get(0);
}
return courseEntity;
}
5.3 Análisis de código
Para el desarrollo de esta aplicación se ha hecho uso de Android Studio, el entorno de
desarrollo integrado oficial de Android. Este IDE, basado en el software Intellij IDEA de
JetBrains, proporciona al programador una herramienta de inspección de código. Gracias
a esta herramienta, se puede detectar y corregir código anómalo en el proyecto antes de
su compilación, además de señalar a posibles mejoras en el rendimiento y la estructura del
código. Entre los problemas que puede detectar están los de código en desuso, posibles bugs
o faltas de ortografía.
Para complementar al análisis de código de Java, Android Studio incorpora la herramienta
Android Lint, que escanea las fuentes de un proyecto de Android para encontrar posibles
bugs. Algunos ejemplos de errores que puede detectar Lint son: falta de traducciones o el
desuso de estas, problemas de rendimiento en el layout, recursos sin usar o problemas de
internacionalización y accesibilidad entre otros.
La herramienta de inspección de código ha sido de ayuda a la hora de mejorar los siguien-
tes aspectos del código:
Android:
45
5 Implementación
• Evitar renderizaciones de fondos innecesarias.
• Eliminar recursos en desuso.
• Evitar fugas de memoria.
Java:
• Aumentar la restricción en modificadores de acceso.
• Eliminar recursos en desuso.
• Evitar NullPointerException.
• Actualizar dependencias y clases API obsoletas.
46
6Conclusiones y trabajo
futuro
6.1 Conclusiones
Tras el estudio del funcionamiento de la aplicación TechPeopleCare App y el tiempo de
desarrollo empleado en ella, se puede concluir que las decisiones tomadas en cuanto a aquello
que concierne a su arquitectura fueron acertadas. Seguir filosofías como Clean Code y aplicar
la inyección de dependencias, dos características clave de esta aplicación, ha requerido un
tiempo de adaptación. Pero una vez asimilados y aplicados estos conceptos, se entiende su
función crucial y el papel que juegan a la hora de tener una aplicación fácil de mantener y
adaptable a los cambios. Esto último es un factor muy importante a tener en cuenta, ya que el
ecosistema de los dispositivos móviles está en constante cambio; bien en lo que concierne a
la plataforma de Android en sí, o bien a lo que a las características de los propios dispositivos
se refiere.
Las pruebas realizadas en entornos reales han sido todo un éxito; ya fuera en los cursos
de alfabetización digital en árabe para mujeres migrantes realizados en Madrid o en los cur-
sos para la tercera edad realizados en Utrech, Holanda. Esto evidencia la necesidad de no
olvidar que existen colectivos en la sociedad que pueden quedar al margen de los avances
tecnológicos más esenciales. Y es primordial que el sector tecnológico tienda una mano a
47
6 Conclusiones y trabajo futuro
estos colectivos, ayudando a que el máximo número de personas puedan acceder a todos los
beneficios que otorgan una sociedad vertebrada por una creciente e inevitable digitalización.
6.2 Trabajo futuro
Entre las posibles mejoras de la aplicación está la adición de la persistencia de un estado
de visto en los vídeos una vez se ha finalizado su visualización, además de guardar el último
punto visto de un vídeo para que un usuario pueda dejar un vídeo por la mitad y que, al
volver a reproducirlo, pueda retomarlo por el punto en el que estaba. Finalmente, en cuanto
a persistencia de estados se refiere, también se está considerando que el curso y sus vídeos
persistan como descargados, con el fin de no comprobar la descarga de todos los vídeos cada
vez que se inicia la aplicación.
Con la introducción de View Binding en Android en el año 2019, el desarrollo de la bi-
blioteca ButterKnife (5.1.4) comienza a entrar en declive, por lo que habrá que migrar de
ButterKnife a la biblioteca de apoyo Data Binding Library.
Además de estos cambios previstos, conforme la aplicación llegue a más usuarios, surgi-
rán nuevas necesidades por parte de los usuarios que tendrán que cubrirse; ya sea añadiendo
nuevas funcionalidades o efectuando aquellos cambios sobre la aplicación que sean necesa-
rios.
48
Bibliografía
[1] R. C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship, 1.a ed. USA:
Prentice Hall PTR, 2008, ISBN: 0132350882.
[2] ——, Agile Software Development, Principles, Patterns, and Practices, 1.a ed. USA:
Prentice Hall PTR, 2003, ISBN: 978-0135974445.
[3] A. Syromiatnikov y D. Weyns, «A Journey through the Land of Model-View-Design
Patterns», abr. de 2014, págs. 21-30, ISBN: 978-1-4799-3412-6. DOI: 10.1109/WICSA.
2014.13.
49
Este documento esta firmado porFirmante CN=tfgm.fi.upm.es, OU=CCFI, O=Facultad de Informatica - UPM,
C=ES
Fecha/Hora Tue Jan 14 23:43:26 CET 2020
Emisor delCertificado
[email protected], CN=CA Facultad deInformatica, O=Facultad de Informatica - UPM, C=ES
Numero de Serie 630
Metodo urn:adobe.com:Adobe.PPKLite:adbe.pkcs7.sha1 (Adobe Signature)