2010-10-08 18 views
7

Estoy buscando alguna crítica sobre mi enfoque para almacenar el estado de un editor de mapas de bits para teléfonos móviles con Android e iPhone. Incluso un "¡Me parece bien!" la respuesta sería genial!Guardar/cargar el estado del documento de forma rápida y robusta para el editor de imágenes

En la aplicación, el documento de usuario actual contiene varias capas de mapa de bits (cada una tal vez 1024 por 768 píxeles) que pueden pintarse. Los requisitos básicos para la aplicación son:

  1. Necesito poder guardar y restaurar el estado del documento.

  2. Cuando el usuario sale de la aplicación o recibe una llamada telefónica, necesito poder guardar el estado del documento rápidamente (en aproximadamente 2 segundos).

  3. Si la aplicación falla, necesito poder restaurar el estado del documento (está bien si el usuario pierde quizás 30 segundos de trabajo).

Para 1, no puedo encontrar ningún formato de archivo abierto que admita capas. Iba a ir con la estructura siguiente archivo para almacenar mi documento:

document_folder/ 
    layer1.png 
    layer2.png 
    ... 
    metadata.xml 

Las capas son sólo almacenan como archivos .png y el archivo .xml contiene datos tales como las capas que están visibles. La carpeta del documento puede abrirse tal cual o la carpeta puede almacenarse en un archivo .zip. Esto parece un buen formato simple para que otras aplicaciones también funcionen.

Además de los archivos .png, también permitiré que las capas se guarden en un formato de archivo .raw personalizado que contenga datos en bruto de píxel no procesados ​​de mapas de bits. Puedo guardar estos muy rápidamente en el teléfono (< 0.5s) mientras que los archivos .png toman uno o dos segundos.

Mi plan para guardar rápidamente el documento era, en el inicio, crear una carpeta llamada/autoguardar y guardar las versiones .raw de todas las capas allí. Después de unos pocos comandos de edición en una capa, actualizaría el archivo .raw para esa capa en una cadena de fondo. Para mayor robustez al guardar, guardaría la capa como p. layer1_tmp.raw y cuando confirme que el archivo se ha escrito completamente, reemplace layer1.raw con este archivo.

En caso de que la aplicación falle durante el uso, simplemente volvería a abrir la carpeta/autoguardar. Cuando la aplicación se cierra o el usuario recibe una llamada telefónica, solo tengo que actualizar la última capa modificada para guardar automáticamente. Cuando el usuario quiere guardar, simplemente convierto todos los archivos .raw en archivos .png y luego comprime la carpeta.

¿Qué opinas? ¿Hay algún defecto obvio? ¿Hay alguna forma más simple? ¿Estoy reinventando la rueda de alguna manera? Gracias.

+3

@tifftuff: "Cuando el usuario sale de la aplicación o recibe una llamada telefónica, necesito poder guardar el estado del documento rápidamente (en unos 2 segundos)" - eso puede no ser posible solo debido a la velocidad de escribiendo para flashear. Flash es muy impredecible en términos de escritura, ya que depende de cosas como la nivelación del desgaste. De lo contrario, no veo nada particularmente malo con su estrategia, al menos * vis a vis * Android. – CommonsWare

+0

@CommonsWare: en Android, puedo copiar 1.5Mb de bytes de píxeles de un objeto Bitmap en un archivo a través de RandomAccessFile.write y luego cerrar el archivo dentro de ~ 0.1s. Si llamo a .sync() en el descriptor de archivo (para forzar que la escritura se realice ahora), lleva algo así como 1 a 3 segundos. No tendré tiempo suficiente para esperar .sync() en el método activity onPause(), pero podría esperar a que termine .close(). ¿No es esto suficiente para tener una buena posibilidad de que el archivo haya sido escrito? ¿Alguna sugerencia sobre lo que puedo hacer si este no es el caso? Solo necesito guardar una capa (~ 1.5Mb). – memcom

+3

@tifftuff: Todo lo que digo es que el flash es lento. En la conferencia 2010 de Google I/O, Brad Fitzpatrick citó algunos experimentos que ejecutó, donde escribir un solo byte esporádicamente tomaría 200ms, aunque típicamente era de menos de milisegundos. Asegúrese de que sus pruebas de tiempo se realicen en el hardware, ya que tienen características tan diferentes como el disco duro que probablemente tenga en su máquina de desarrollo. Cuantos menos datos escribas, más rápido será. Por ejemplo, tal vez lo que está pensando como una "capa" debería ser simplemente los píxeles que se dibujan, no cualquier fondo, para tratar de reducir ese 1,5 MB hacia abajo. – CommonsWare

Respuesta

0

Creo que tienes un gran plan allí. Probablemente iría de la misma manera (pero eso en sí mismo no significa nada :-)

Lo que estaba pensando es si podría tener no solo un hilo de trabajo guardando el archivo sino un servicio de fondo completo (con un hilo de trabajador por supuesto, ya que un servicio en sí mismo también se ejecuta en el hilo principal).

De esta manera, usted habría garantizado que siempre hay algo vivo que puede manejar los deltas de su capa, independientemente de si la actividad de dibujo se ha bloqueado o si alguien lo está llamando. De repente, no tiene las mismas restricciones de tiempo (la operación de escritura puede tomar 10 segundos si así lo desea, su actividad no está bloqueada ni depende de la operación de escritura).Por supuesto, su servicio se suicidará cuando haya vaciado su cola de guardado (para guardar los recursos del sistema).

Lo que no sé para promover aún más esta idea es ¿cuántos datos está escribiendo en el archivo sin formato? ¿Escribes la capa completa de 1024x768 cada vez o solo reescribes las partes modificadas? Tampoco estoy seguro de cómo se transmitirán realmente los datos al servicio (de la Actividad). No sé si hay un tamaño máximo de un byte-array-extra que Intent pueda manejar.

Espero que esto te brinde más ideas.

¡Salud!

1

Tu idea es muy buena para mí: guarda las capas en el fondo, sobre la marcha. Cualquier capa que el usuario no está editando actualmente debe ponerse en cola para que se guarde tan pronto como se cambie de una capa diferente. Si la aplicación se interrumpe, solo tienes que guardar la capa de trabajo actual, que como dices se puede hacer en 0.5 segundos.

¿Por qué molestarse con el formato png de todos modos? Solo lo necesita si exporta datos a otra máquina/sistema, ¿verdad?

+0

Muy cierto. Png solo es necesario si desea que el usuario pueda exportar. Así que tal vez solo genere un png si un usuario hace clic en exportar o similar. De lo contrario, solo use su formato rápido sin formato. Tu enfoque suena genial. –

Cuestiones relacionadas