Evitar la compresión de los «assets» en Android

Si alguna vez has necesitado incluir un recurso de gran tamaño en el directorio de «assets» de tu proyecto Android, seguramente has encontrado problemas al utilizarlo en teléfonos móviles que no estuviesen actualizados a Gingerbread, ya que al probar la aplicación te encontrabas con que el fichero se corrompía, o no era tal cual esperabas (es decir, como era originalmente). En este post os explicamos qué es lo que sucede, y cómo evitarlo… porque todo tiene una explicación.

Al generar el fichero distribuible de una aplicación android (el fichero APK), los recursos para una aplicación Android (ya sean ficheros XML, imágenes, o cualquier otro tipo de fichero contenido en los directorios «Res» o «Assets» de Android) se procesan a través del «Android Asset Packaging Tool», o aapt.

En este proceso se genera el fichero empaquetado, una especie de ZIP formateado para Android, en cuyo proceso de construcción se procesan los recursos y, por defecto, el sistema comprimirá varios tipos de recursos para que el resultado ocupe menos. El sistema decide qué ficheros comprimir en base a su extensión, como se ve en este código de «Package.cpp»:

/* these formats are already compressed, or don't compress well */
static const char* kNoCompressExt[] = {
    ".jpg", ".jpeg", ".png", ".gif",
    ".wav", ".mp2", ".mp3", ".ogg", ".aac",
    ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
    ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
    ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
    ".amr", ".awb", ".wma", ".wmv"
};

De esta forma, podemos saber cuáles son los tipos de ficheros que Android «no tocará» a la hora de generar el instalable. Esta lista es especialmente útil en caso de que necesitemos incluír algún recurso de gran tamaño en nuestra aplicación. Por ejemplo, para incluir una base de datos SQLite de varios MB de tamaño, evitando que el sistema aapt comprima el fichero y, por tanto, lo estropee.

Para evitar la compresión de nuestro recurso habremos de agregarle una de las extensiones «seguras». Por ejemplo, renombrando nuestra base de datos «basedatos.sqlite» a «basedatos.mp3». Con esta pequeña «chapuza» evitaremos que Android procese nuestra base de datos, corrompiendo la información dentro de ella.

NOTA: esta solución sólo es necesaria para versiones de Android anteriores a 2.3. A partir de esta versión se modificó el sistema de gestión de «assets», con lo cual no sería necesario cambiar la extensión, pero si queremos que la aplicación sea compatible con versiones anteriores será necesario llevar a cabo esta solución.

Vía | Ponystyle Industries.