Intel Learning Series para desarrolladores para Android*, n.º 9:Representación de gráficos en Android para la arquitectura Intel® mediante el uso de la biblioteca SVG

Scalable Vector Graphics* (que significa Gráficos Vectoriales Redimensionables y se conoce por sus siglas SVG) es una familia de especificaciones de un formato de archivo basado en XML para gráficos vectoriales bidimensionales, tanto estáticos como dinámicos (es decir, interactivos o animados), texto o gráficos de trama incrustados. La especificación SVG es un estándar abierto exento del pago de regalías e independiente del proveedor que ha estado desarrollando el World Wide Web Consortium* (W3C) desde 1999.

Las imágenes SVG y su comportamiento se definen en archivos de texto XML. Esto significa que se las puede buscar, indexar, incluir en scripts y, si es necesario, comprimirlas. Al ser archivos XML, se las puede crear y modificar con cualquier editor de texto.

Los archivos SVG son compactos y proporcionan gráficos de alta calidad en la Web, en impresiones y en dispositivos de mano con recursos limitados. Además, SVG es compatible con el scripting y la animación, así que es ideal para gráficos interactivos, controlados por datos y personalizados.

Usar SVG ofrece muchos beneficios. En primer lugar, no es necesario tener imágenes en diferentes resoluciones ni hacer redimensionamientos. En segundo lugar, SVG es un archivo XML, así que su tamaño es mucho menor que el correspondiente en formato de trama para la misma imagen. Esto también es útil para cambiar la imagen al vuelo.

SVG admite tres tipos de objetos gráficos: gráficos vectoriales, gráficos de trama, y texto. Los objetos gráficos, incluidas las imágenes de trama PNG y JPEG, se pueden agrupar, transformar, se les puede aplicar un estilo y se los puede componer en objetos ya representados.

Las aplicaciones nativas de Android* no admiten archivos XML SVG. Pero los archivos XML SVG se podrían analizar en exploradores a partir de Android 3.0 (ver Figura 1). En este capítulo se integra la biblioteca open source SVG-Android a la base de código y se brinda una aplicación de ejemplo en Android Ice Cream Sandwich (ICS) sobre arquitectura Intel®.

1. Funcionalidad de SVG

La especificación SVG 1.1 define 14 áreas funcionales de conjuntos de características, a saber:

  • Rutas
  • Formas básicas
  • Texto
  • Pintura
  • Color
  • Gradientes y tramas
  • Recorte, enmascaramiento y composición
  • Efectos de filtro
  • Interactividad
  • Vinculación
  • Scripting
  • Animación
  • Fuente
  • Metadatos

2. Formas de SVG

Los elementos de forma predeterminados de SVG son:

  • Rectángulo <rect>
	<svg>
<rect x="50" y="20" width="150" height="150" style="fill: red;
stroke: yellow; stroke-width: 5; opacity: 0.5" />
</svg>
  • Círculo <circle>
<svg >
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2"
fill="red" />
</svg>
  • Elipse <ellipse>
  • Línea <line>
  • Polilínea <polyline>
  • Polígono <polygon>
  • Ruta <path>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">

<path d="M150 0 L75 200 L225 200 Z" />
</svg>


Figure 1. Implementación de SVG en dispositivo Android
Fuente: Intel Corporation, 2012

3. Integración de la biblioteca SVG

Cree un archivo de nombre svgandroid.xml para describir svgandroid.jar. Coloque svgandroid.jar en la carpeta /system/framework y svgandroid.xml en la carpeta /etc/permissions. Las aplicaciones descubrirán la biblioteca svgandroid.jar mediante svgandroid.xml.

Agregue el siguiente código a svgandroid.xml:

<?xml version="1.0" encoding="utf-8">
<permissions>
<libraryname="svgandroid" file="/system/framework/svgandroid.jar"/>
</permissions>

Use la declaración <use-library> en el archivo AndroidManifest.xml. Este método carga los paquetes de svgandroid. No se cargan automáticamente.

<uses-library android:name="svgandroid" android:required="true" />

Establezca android:required="true". El sistema Android no permitiría aplicaciones en un dispositivo sin esta biblioteca.

Si se instala esta aplicación en dispositivos Android sin esta biblioteca, aparece el siguiente mensaje de error:

Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY]

Este elemento afecta también la disponibilidad de esta aplicación en Market. El dispositivo Android no podría incluir esta aplicación en Market sin la biblioteca.

4. Cómo representar un archivo con SVG modificada

En esta sección se muestra cómo representar un archivo mediante el uso de SVG modificada.

4.1. ¿Qué es SAX?

SAX (Simple API for XML) es una API analizadora de acceso secuencial basada en eventos que genera la lista de correo de XML-DEV para los documentos XML. El mecanismo de SAX para leer datos de documentos XML es muy diferente del que proporciona el Document Object Model (DOM). Mientras que el DOM opera en el documento como unidad, los analizadores SAX operan en cada parte del documento XML de manera secuencial.

4.2. Beneficios

Los analizadores SAX ofrecen ciertos beneficios respecto de los analizadores estilo DOM. Normalmente, usan mucha menos memoria. Los analizadores DOM deben tener el árbol completo en la memoria antes de poder comenzar a procesar, así que la memoria que usan depende por completo del tamaño de los datos de entrada. La superficie de memoria de los analizadores SAX, en cambio, sólo se basa en la profundidad máxima del archivo XML (la profundidad máxima del árbol XML) y la cantidad máxima de datos almacenados en los atributos XML de un solo elemento XML. Estos valores son siempre menores que el tamaño del árbol analizado.

Como SAX se basa en eventos, con frecuencia el procesamiento de documentos es más rápido que en los analizadores estilo DOM. La asignación de memoria lleva tiempo, así que la mayor superficie de memoria del DOM constituye también un problema de rendimiento.

Debido a la naturaleza del DOM, es imposible leer por secuencias desde el disco. También es imposible con estos analizadores procesar documentos XML más grandes que la memoria principal, pero es algo que se puede hacer con los analizadores SAX. Sin embargo, los analizadores DOM pueden usar espacio de disco como memoria para esquivar esta limitación.

4.3. Desventajas

El modelo basado en eventos de SAX es útil para analizar documentos XML, pero tiene algunos inconvenientes.

Para ciertos tipos de validación de XML se requiere acceso a todo el documento. Por ejemplo, un atributo DTD IDREF requiere que haya un elemento en el documento que use la cadena dada como atributo DTD ID. Para hacer esta validación en un analizador SAX, sería necesario hacer un seguimiento de todos los atributos ID e IDREF encontrados para ver si hay alguna coincidencia. Además, si un IDREF no se empareja con un ID, el usuario recién lo descubre después de que se ha analizado el documento. Si esta vinculación fuera importante para crear salidas funcionales, entonces se habría desperdiciado tiempo en procesar todo el documento para que al final no sirva.

Además, algunos tipos de procesamientos de XML exigen tener acceso a todo el documento. XSLT y XPath, por ejemplo, necesitan poder acceder en cualquier momento a cualquier nodo del árbol XML analizado. Si bien se podría usar un analizador SAX para construir ese árbol, el DOM ya está diseñado para hacerlo.

4.4. Cómo implementar el analizador SAX en Android

Cuando se implementa un analizador SAX, es necesario que la clase herede “DefaultHandler". Y hay varios métodos que se deben invalidar para heredar “DefaultHandler" (la clase de base predeterminada para controladores de eventos SAX2 en Android). Estos métodos son startElement, endElement, startDocument y endDocument. El nombre de cada función describe lo que hace. Por ejemplo, startDocument significa que cuando el SAX comienza a analizar el documento, desencadena un evento y llama al método startDocument. Una vez que el SAX analiza una etiqueta cualquiera de archivo XML, llama a startElement para que se pueda obtener el nombre de la etiqueta, el atributo y más información pertinente de la etiqueta. Los otros métodos, endDocument, startElement y endElement, se explican por sí mismos.

4.5. ¿Cuál es la razón para modificar la biblioteca SVG original?

Como la biblioteca original no puede representar el archivo con atributos en la etiqueta de grupo (<g>), debemos agregar un registro para guardar el atributo de estilo con una etiqueta <g>. Si ya hay un atributo de estilo en el elemento de representación interno, el atributo de estilo reemplazará al de la etiqueta <g>.

Recomendamos usar SAX para analizar el archivo SVG. Cuando analizamos la etiqueta <g>, recuperamos todo el atributo para la instancia –g_prop, que es una clase interna de las propiedades.

public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException
{
... ...
} else if (localName.equals("g")) {
... ...
pushTransform(atts);
g_prop = new Properties(atts);
}
... ...
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException
  
{
... ...
} else if (localName.equals("g")) {
... ...
pushTransform(atts);
g_prop = new Properties(atts);
}
... ...
}

Cuando analizamos <rectangle>, <path> o cualquier otra etiqueta de representación, necesitamos revisar si hay algún estilo asociado a la etiqueta. Si lo hay, debemos obtener los atributos. Los métodos doFill, doStroke ayudan a iniciar el estilo de llenado y trazo del lienzo. Una vez invocados los métodos, podemos dibujar el elemento analizado en el lienzo.

Properties props = new Properties(atts);
if (doFill(props, gradientMap))
{
doLimits(p);
canvas.drawPath(p, paint);
}
else
{
if(g_prop != null)
{
if(doFill(g_prop, gradientMap))
{
doLimits(p);
canvas.drawPath(p, paint);
}
}
}
if (doStroke(props))
canvas.drawPath(p, paint);
else
{
if(g_prop != null)
{
if(doStroke(g_prop))
canvas.drawPath(p, paint);
}
}
popTransform();
}
Properties props = new Properties(atts);
if (doFill(props, gradientMap))
{
doLimits(p);
canvas.drawPath(p, paint);
}
else
{
if(g_prop != null)
{
if(doFill(g_prop, gradientMap))
{
doLimits(p);
canvas.drawPath(p, paint);
}
}
}
  
if (doStroke(props))
canvas.drawPath(p, paint);
else
{
if(g_prop != null)
{
if(doStroke(g_prop))
canvas.drawPath(p, paint);
}
}
popTransform();
}

3.6. Archivo XML SVG con atributos en la etiqueta de representación

El siguiente es un archivo XML SVG con atributos en la etiqueta de representación (ver Figura 2).

<path display="none" fill="#FFFFFF" d="M268.461,471.01c2.526,0,4.575,2.048,4.575,4.571c0,2.529-2.049,4.576-4.575,4.576 c-2.525,0-4.574-2.047-4.574-4.576C263.887,473.058,265.936,471.01,268.461,471.01z"/>


Figure 2. Implementación de SVG en dispositivo Android
Fuente: Intel Corporation, 2012

4. Archivo XML SVG con atributos en la etiqueta de grupo

El siguiente es un archivo XML SVG con atributos en la etiqueta de grupo.

<g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">

<path d="M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z"/>

</g>


Figure 3. Implementación de SVG en dispositivo Android
Fuente: Intel Corporation, 2012

Einzelheiten zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.