Mecanismos de Persistencia en Android
-
Upload
javier-munoz -
Category
Technology
-
view
1.818 -
download
2
description
Transcript of Mecanismos de Persistencia en Android
1
Mecanismos de Persistencia en
Android
Febrero 2014
Javier Muñoz Ferrara [email protected] http://twitter.com/jmunozf
http://www.linkedin.com/in/javiermf
2
§ Holding familiar. 3ª Generación
§ Más de 30 empresas.
§ Con 2.500 empleados.
§ Presente en 9 Comunidades.
§ Dando servicio a más de 1 millón de personas.
La empresa
3
La empresa
GSC
Área Software
4
Área DataCenter y Comunic. Área de Microinf.
DEPARTAMENTO DE T.I.C.
28 personas
La empresa
Desarrollos a medidas en entornos VB y Java
Proyectos de movilidad Android
Web Responsive
Desarrollos Web: Intranets corporativas
Extranets
Portales webs
Gestión Documental
Sist. de información Geográfica (GIS)
SAP R3 – BI/BO
Administración de servidores y BBDD.
Virtualización de servidores
Gestión de comunicaciones y radioenlaces/WIFI
Cloud privado - CPD propio (Tier III)
Mantenimiento integral
microinformático.
Asistencia remota
Soporte online
Auditorias del parque tecnológico.
Soporte de Helpdesk
Externalización de equipos de
impresión.
Venta de material informático
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
Almacenar los datos de la aplicación
para que estén disponibles al reiniciar
el software
Conceptos básicos ¿Qué es la persistencia?
Las aplicaciones se reinician
La RAM es limitada
Conceptos básicos ¿Por qué es necesaria?
Conceptos básicos ¿Es importante?
La persistencia suele ser imprescindible
para el correcto funcionamiento de las
aplicaciones
Conceptos básicos ¿Es LO MÁS importante?
NO. Lo más importante son las reglas
de negocio de los usuarios/clientes
¿Entonces por qué muchas veces empezamos
diseñando e implementando la base de datos?
Conceptos básicos ¿Cómo persistir los datos?
Al usuario/cliente probablemente no le interese
BBDD NoSQL
BBDD Relacionales Archivos Binarios
CSV
XML
Almacenamiento Cloud Servicios Web
Conceptos básicos ¿Cómo persistir los datos?
¿Cómo podemos persistir en Android?
§ Preferencias § Parejas: clave -> valor
§ Configuraciones, recordar acciones, etc.
§ Almacenamiento de archivos § Almacenamiento interno o externo
§ Archivos arbitrarios (imágenes, json, xml, texto, binarios, etc.)
§ Datos estructurados § Base de datos SQL
§ Colecciones de datos estructurados y relacionados
Tipo de Persistencia ¿Cómo realizar la persistencia en móvil?
Local § Almacenamiento en el propio móvil
§ Especio limitado. Acceso rápido. Alto coste consultas complejas
1.-
Tipo de Persistencia ¿Cómo realizar la persistencia en móvil?
Remota en un servidor § El móvil sólo muestra datos, que lee de un servidor
§ Cada acceso a datos requiere un consulta
§ Alta latencia. Muy sensible a desconexiones
2.-
Tipo de Persistencia ¿Cómo realizar la persistencia en móvil?
Mix (Cacheo/Hoarding) § Copia local de alguna información del servidor
§ Comunicación con el servidor para sincronizar
§ Funcional (más o menos) desconectado. Latencia según acierto.
3.-
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
Retos Espacio limitado
Almacenamiento local § Memoria interna/Memoria externa
§ Varios GB (no está mal)
Seleccionar datos a persistir
Retos Computación y memoria limitada
Consultas complejas lentas § Mejor preprocesar datos en el servidor
§ Desnormalizar BBDD si es posible
Alto consumo de batería
Retos Restricciones de comunicación
Dificultad para sincronizar § Minimizar número de conexiones
§ Sólo datos relevantes para la aplicación
§ Sólo modificaciones a los datos
§ Preprocesar datos
Retos Desconexiones habituales
Modo off-line. ¿Qué ocurre? § No funciona nada
§ Funcionamiento limitado (sólo lectura)
§ Funcionamiento completo (conflictos)
Recuperación conexión § Sincronización de datos
§ Resolución de conflictos
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
El camino sin reflexionar
Diseñar y crear la BBDD
Escribir SQL donde haga falta leer o modificar datos
Utilizar cursores para recorrer los resultados
Con el paso del tiempo
¿Y si cambio el nombre o tipo de una columna?
¿Y si añado una tabla nueva?
¿Y si cambio BBDD local por servicios web externos?
Diseño de la persistencia
Originario del ámbito J2EE
Aplicable a cualquier tipo de software OO
Patron DAO Data Access Object
Patrón DAO ¿Qué es?
Interfaz con métodos de persistencia para Bussiness Objects
Independiente del mecanismo de persistencia (BBDD, XML, Servicios
Web, etc.)
Sólo entran y salen Bussiness Objects y tipos primitivos
Excepciones independientes de la persistencia
Patrón DAO ¿Qué es?
Entran y salen objetos, pero la lógica de la aplicación no
sabe cómo se guardan
Patrón DAO Beneficios e Inconvenientes
Separación lógica aplicación y gestión persistencia
Evolución/Migración persistencia sin cambiar lógica aplicación
Centralización de las tareas de persistencia (mejor mantenimiento)
Capa extra quizá innecesaria en aplicaciones pequeñas
Mueve objetos enteros -> Sobrecarga (si no se diseña bien)
Dificulta integración con frameworks ActiveRecord u ORM
Beneficios
Inconvenientes
Patrón DAO Estructura habitual
Un objeto DAO por Bussiness Object/Tabla
Métodos habituales en el interfaz List<BO> getAll() / findAll()
BO getById(Long id) / findById(Long id)
insert(BO theObject)
delete(BO theObject)
update(BO theObject)
Y todos los que hagan falta….
Patrón DAO Métodos Genéricos vs Métodos Específicos
Ejemplo: Aplicación tipo Google Calendar (vista calendario + vista detalle)
Métodos genéricos List<Event> getAllEvents()
Event insertEvent(Event e)
Event updateEvent(Event e)
Métodos genéricos
List<Event> getAllEventsWithScheduleInfo()
updateScheduleInfo(long eventId, Date start, Date end)
Event insertEvent(String title, Date start, Date end)
Event getEventWithDetailnfo()
Event updateEvent(Event e)
DAO permite varias persistencias. ¿Para qué?
Conectado vs Desconectado
Desarrollo vs Producción
Lite vs Premium
Conexión rápida vs Conexión lenta
¿Cómo cambiar entre persistencias?
UsuariosDAO usuariosDAO = new UsuariosSQliteDAO();
UsuariosDAO usuariosDAO = new UsuariosRESTDAO();
¡Disperso por toda la aplicación!
¿Cómo cambiar de persistencia?
Patrón DAO Abstract Factory Pattern
Factoría -> encargado de crear objetos
Agrupar y encapsular factorías individuales (una por DAO)
DAOFactory
getUsersDAO() getProducsDAO()
SqliteDAOFactory
getUsersDAO() getProducsDAO()
RestDAOFactory
getUsersDAO() getProducsDAO()
<implementa>
UserSqliteDAO ProductsSqliteDAO
UserRestDAO ProductsRestDAO
Patrón DAO Abstract Factory Pattern
DAOFactory
getUsersDAO() getProducsDAO()
SqliteDAOFactory
getUsersDAO() getProducsDAO()
RestDAOFactory
getUsersDAO() getProducsDAO()
<implementa>
MyAppDAOFactory
getUsersDAO() getProducsDAO()
<delega en> <delega en>
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
Android Annotations ¿Por qué utilizarlo?
Facilitar la legibilidad del código
Evitar escribir código boilerplate
Centrarse en la lógica de la aplicación
Ocultar la complejidad técnica
Android Annotations ¿Qué funcionalidad simplifica?
Inyección de dependencias § Obtener referencias a vistas, recursos, extras, etc.
Gestión de threads § UI vs Background
Listeners de eventos § No más clases anónimas
Cliente REST § Interacción con servicios WEB
Android Annotations ¿Cómo funciona?
Anotaciones Java
Generación automática de código boilerplate
Clases que extienden las de la aplicación
Necesario referencias las clases generadas
Android Annotations Ejemplo
SQLite en Android Conceptos básicos
Incluida en por defecto Open Source → Utilizada en otros muchos proyectos
Ligera y embebida
BDs privadas de cada aplicación
Se almacenan en “/data/data/<package-name>/databases”
A tener en cuenta No mantiene integridad de datos
No mantiene integridad referencial (foreign keys) Se puede simular con triggers
Por defecto no tiene soporte completo a Unicode
No proporciona interfaz gráfica de administración
SQLite en Android Implementación
Crear clase para administración: Heredar de android.database.sqlite.SQLiteOpenHelper
Parámetros del constructor: Contexto Nombre de la DB CursorFactory (null para utilizar el por defecto) Versión del esquema de BBD (para tener en cuenta en migraciones)
Implementar métodos de construcción
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+tableName+" (_id INTEGER PRIMARY KEY , "+
colDeptName+ " TEXT)");
// More stuff including initial data
}
SQLite en Android Implementación
Implementar método de migración Parámetros del constructor:
oldVersion: versión de la bbdd en el dispositivo newVersion: versión que se quiere alcanzar
Desde la Actividad:
Crear instancia del DBOpenHelper Conseguir DB
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// do stuff
}
db.getWritableDatabase();
SQLite en Android Interactuando con la BBDD
Consultas (Queries) Modo “raw”:
Modo “sencillo” (API)
SQLiteDatabase db=this.getReadableDatabase();
Cursor cur=db.rawQuery("SELECT "+colDeptID+" as _id,"+colDeptName+" from "+deptTable,new String [] {});
SQLiteDatabase db=this.getReadableDatabase();
String [] columns=new String[]{"_id",colName,colAge,colDeptName};
Cursor c=db.query(viewEmps, columns, colDeptName+"=?",
new String[]{Dept}, null, null, null);
§ Nombre tabla § Columnas § Condición WHERE
§ Argumentos del WHERE § Cláusula GROUP BY § Clásula HAVING
§ Clásulula ORDER BY
SQLite en Android Interactuando con la BBDD
Insertar fila SQLiteDatabase db=this.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(“colDeptID”, 1);
cv.put(“colDeptName”, "Sales");
db.insert(deptTable, “colDeptID”, cv);
cv.put(“colDeptID”, 2);
cv.put(“colDeptName”, "IT");
db.insert(“tablename”, null, cv);
db.close();
SQLite en Android Operaciones con Vectores
Puntero a un conjunto de datos Resultado de una interacción con una BBDD
Operaciones de gestión:
close() deactivate() requery()
Operaciones de consulta: getInt(int column_index) getString(int column_index) Etc. getColumnIndex(String
ColumnName)
Operaciones de posición: moveToNext() moveToFirst()
moveToPosition(int pos)
moveToLast()
isFirst()
isLast()
isBeforeFirst()
isAfterLast()
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
Una técnica de programación para
convertir datos entre un sistema OO y un
sistema Relacional
Object-Relational Mapping ¿Qué es un ORM?
Object-Relational Mapping Impedancia Objeto-Relacional
Relacional Tablas
Orientación a Objetos Grafos
Gestionan la impedancia OO-Relacional
Aplican patrones estándar de correspondencia
OK para el 90% de la funcionalidad necesaria
Object-Relational Mapping Frameworks ORM
Object-Relational Mapping Algunas Recomendaciones
Loggea y lee las SQL que genera el ORM
Utiliza profiling para encontrar queries lentas
Añade los selects para recuperar sólo columnas necesarias
Utiliza raw SQL cuando el ORM complica las cosas
OrmLite ¿Qué es?
http://ormlite.com/
ORM básico para aplicaciones Java
Se integra con MySQL, PostgreSQL, SQL Server, SQLite…
Mapping por anotaciones
Generación dinámicas de DAOs básicos
OrmLite Definició de las correspondiencias
@DatabaseTable(tableName = "samples") public class SampleRow { […] @DatabaseField(columnName = COLUMN_ID, id = true) String id; @DatabaseField(foreign = true, columnName = COLUMN_ROUTEPLANED) RouteRow routeRowPlannedSample; @DatabaseField(foreign = true, foreignAutoRefresh = true) UserRow madeByRow; @DatabaseField(foreign = true, foreignAutoRefresh = true) UserRow takenByRow; @DatabaseField(columnName = COLUMN_KIND) SampleKind kind; @DatabaseField(columnName = COLUMN_CITYNAME) String cityName; @DatabaseField(columnName = COLUMN_COMMENTSFORANALYST) String comment; @ForeignCollectionField(eager = false) public ForeignCollection<SampleParameterRow> samplesParameters; […] }
OrmLite Manipular la BBDD
Instanciar el OpenHelper
Obtener un DAO para un tipo de objeto
@RootContext Context ctxt; Dao<SampleRow, Long> dbDAO; @AfterInject void initDbHelper() { DatabaseHelper dbHelper = OpenHelperManager.getHelper(ctxt, DatabaseHelper.class); try { dbDAO = dbHelper.getDao(SampleRow.class); } catch (SQLException e) { dbDAO = null; } }
OrmLite Manipular la BBDD
Crear un objeto
SampleRow sampleRow = new SampleRow(); sampleRow.setCityName(“Zaragoza”); […] dbDAO.create(sampleRow);
sampleRow.setCityName(“Huesca”); //debe tener id dbDAO.update(sampleRow);
Actualizar un objeto
dbDAO.delete(sampleRow); // o también dbDAO.deleteById(sampleRow.getId());
Eliminar un objeto
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
Servicios de persistencia de manera remota
a través de Internet
Persistencia Cloud ¿Qué es?
Servicios Cloud Ventajas e Inconvenientes
Evitar infraestructura sobredimensionada
Evitar costes de administración y mantenimiento
Distribuir costes en el tiempo
Soportar picos de necesidad
Problemas de privacidad y seguridad
Imposible adaptación/personalización
Difícil respuesta a fallos de servicio
Falta de estándares (vendor lock-in)
Ventajas
Inconvenientes
Persistencia Cloud Ecosistema de Servicios
Acceso por SDK o API REST
SimpleDB (REST + SDK)
MongoDB (REST)
Oracle (custom REST)
Parse Data (REST + SDK)
CouchDB (SDK)
Firebase Data (REST + SDK)
Sistemas de almacenamiento de información que
no cumplen con el esquema entidad-relación
NoSQL ¿Qué es?
No hay consultas con SQL
No hay estructura fija
No hay JOINs
No garantizan ACID (atomicidad, coherencia, aislamiento y durabilidad)
NoSQL ¿Por qué surge?
Aplicaciones Web Globales
- Grandes volúmenes
- Datos heterogéneos
- Rápida evolución de la estructura
- Acceso escalable
Nueva Infraestructura
- Grandes clústers
- Almacenamiento y computación cloud
NoSQL ¿Por qué surge?
Problemas de BBDD Relacionales
- No escalan bien en horizontal (distribución)
- Dificultan las evolución del esquema
Persistencia “Políglota”
- Distintas necesidades -> Distinto tipo de persistencia
- Encapsular para independizar
Datos muy estructurados Volumen reducido Acceso ocasional
Datos poco estructurados Volumen muy grande Acceso constante
Características NoSQL
Schema-less
Facilidades distribución
Consistencia ocasional
Características NoSQL Principales tipos de BBDD NoSQL
Clave->Valor - Como un map enorme
- Particionado sencillo por clave
Document Store - Mapas anidados con listas
- Permiten “consultas” del contenido
Big Table - Filas y columnas
- “Familias” de columnas dinámicas
BBDD Grafos
- Nodos, propiedades y aristas
- Permiten consultas complejas
NoSQL Ventajas e Inconvenientes
Estructura adecuada para algunos datos
Mejor escalabilidad
Más flexibilidad de la estructura de datos
Aplicaciones más complejas
Falta de estandarización/formación
Integración estrategias persistencia
Ventajas
Inconvenientes
Parse Conceptos Básicos
Parse Data - Parte de suite de servicios para desarrollo de apps
- Notificaciones PUSH, Identificación, Analíticas…
Instalación
1.- Descargar JAR e incluir
2.- Inicializar librería
Parse.initialize(this, APP_CODE, API_KEY);!
Parse Manipular datos
Guardar datos
Consultas
ParseObject parseObject = new ParseObject("Note");!
parseObject.put("title",note.getTitle());!
parseObject.put("text",note.getText());!
parseObject.put("category",ParseObject.createWithoutData("Category",note.getCategory().getId()));!
!
ParseQuery<ParseObject> query = ParseQuery.getQuery("Note"); !
for (ParseObject parseObject : query.find()) { …. }!
!
ParseObject parseObject = query.get(noteToEditId);!
¿Qué es persistencia?
Retos de la persistencia en móviles
¿Cómo diseñar la persistencia de datos?
Mecanismos de persistencia de datos en Android
SQLite
ORMLite
Parse
Servicios REST
Índice
El Representational State Transfer (REST)
es un estilo arquitectónico para sistemas
software distribuidos basado en
RECURSOS
REST ¿Qué es?
Cliente <- Recurso -> Servidor
REST ¿Qué es?
BBDD API REST
Aplicación Software
RECURSO
Cualquier concepto con significado en la
aplicación que puede ser nombrado
REST Recursos
CLIENTE FACTURA
LUGAR
TIENDA COMENTARIO
Basado en URLs (Human readable)
Recomendaciones:
REST Nombrado
http://example.com/customers/1234 http://example.com/orders/2007/10/776654/products http://example.com/bills/4554/lines/6
recurso subrecurso
- No utilizar nombres de acción - Evitar parámetros (si es posible)
- Denominación en plural
Acciones estándar definidas en HTTP
REST Acciones
Comando HTTP Acción Código
respuesta Contenido respuesta
GET Lectura Código 200 (OK)
El recurso/s consultado/s
POST Creación Código 201 (Created) El recurso creado
PUT Modificación Código 200 (OK)
El recurso modificado
DELETE Eliminación Código 204 (No content) Nada
Representación en texto del recurso (human-readable)
- JSON, XML, HTML, YAML, RSS, ATOM
REST Representación
JSON XML
q Leer un stream
REST Conexión HTTP manual
String getURL = “http://nombredelservidor.com/services/clientes/”+clienteId;
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
is = conn.getInputStream();
JSONObject clienteJsonObject = new JSONObject(is.toString());
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(clienteJsonObject, Cliente.class);
q Definir una interfaz
REST Con Android Annotations
@Rest(rootUrl = "http://nombredelservidor.com/services/",converters = { MappingJacksonHttpMessageConverter.class })
public interface ClientesClient {
@Get(”clientes/{clientId}")
Client getClienteById(String clientId);
}
La persistencia es un detalle (importante)
Varias opciones/tecnologías de implementación
Elija una, pero no hipoteques tu futuro
Mecanismos de Persistencia en Android Conclusiones
74
Mecanismos de Persistencia en Android
Javier Muñoz Ferrara [email protected] http://twitter.com/jmunozf
http://www.linkedin.com/in/javiermf