2012-01-16 13 views
7

estoy usando este sencillo formato de fechaSimpleDateFormat lleva demasiado tiempo cuando la zona horaria se incluye

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z"); 

el problema es cuando utilizo este se tarda demasiado tiempo para convertir el tiempo, en Logcat veo algo como esto

I/Resources(4284): Loaded time zone names for en in 272ms. 
I/Resources(4284): Loaded time zone names for en in 194ms. 
I/Resources(4284): Loaded time zone names for en in 112ms. 
I/Resources(4284): Loaded time zone names for en in 111ms. 
I/Resources(4284): Loaded time zone names for en in 113ms. 
I/Resources(4284): Loaded time zone names for en in 127ms. 
I/Resources(4284): Loaded time zone names for en in 253ms. 
I/Resources(4284): Loaded time zone names for en in 110ms. 
I/Resources(4284): Loaded time zone names for en in 154ms. 
I/Resources(4284): Loaded time zone names for en in 112ms. 

¿Cómo puedo usar sencilla formater fecha, pero para acelerar las cosas, no quiero tomar ~ 150 ms para cada conversión ...

¿alguien ha tenido este problema antes?

+0

publique su código ... –

+0

Si es la zona horaria que lo desacelera, puede calcularlo una vez y luego agregarlo como una para cada formato, ya que es poco probable que la zona horaria cambie. – Jave

+0

este es el código, la demora está en el nuevo SimpleDateFormat ("aaaa-MM-dd HH: mm: ss.SSS Z "); y es porque tengo la zona incluida, si ejecuto mi código con el nuevo SimpleDateFormat (" aaaa-MM-dd HH: mm: ss.SSS "); [sin la zona horaria] funciona bien , el único problema es cuando se incluye el huso horario simplemente toma demasiado tiempo No sé por qué – Lukap

Respuesta

10

Esto se debe a la inicialización diferida de las cadenas de zonas de la zona horaria. Solo la primera llamada tardará tanto. Si SimpleDateFormat se utiliza de nuevo después, es cargado desde la memoria caché y ya no debería demorar tanto.

Antes de que esto se cambiara se hizo cuando la clase se cargó y por lo tanto el inicio de una actividad tomó esos 2-3 segundos más. Esto tuvo un impacto mucho peor en la experiencia del usuario que si tardara esos segundos cuando se usa realmente la primera vez. El problema es que no hay forma ahora de eludir este problema debido al diseño de la api SimpleDateFormat. Solo los teléfonos más rápidos pueden solucionar esto al tomar menos tiempo para recopilar esas cadenas.

El almacenamiento en caché ocurre en DateFormatSymbols que SimpleDateFormat está usando. Por reutilizando esa instancia, solo es posible cargar las picaduras una vez (para el misma propiedad). También puede crear esa instancia en un hilo al inicio de la actividad para que esté en la memoria caché una vez que se haya utilizado. Para iniciar las cadenas simplemente llame al .hashCode() que forzará la inicialización de la caché. Un poco más rápido pero menos simple sería ser serializar la instancia. Esto también obliga a inicializar la memoria caché.

Mientras tanto, considere utilizar AsyncTask para "calentar" SimpleDateFormat en su proceso antes de que lo necesite. Simplemente analice una fecha en AsinncTask doInBackground() para que cargue las zonas horarias en algún momento cuando no afecte tanto al usuario. Una vez inicializado en su proceso, SimpleDateFormat se ejecutará rápidamente hasta que finalice su proceso.

+1

¿SimpleDateFormat tampoco es seguro para subprocesos en Android? – Somatik

4

Esto no es así en las versiones recientes de Android (y del texto del mensaje de registro puedo decir que está ejecutando una versión anterior; las versiones modernas le dicen cuánto tiempo pasó en icu4c versus código administrado) . Tenga en cuenta que la respuesta de "Pulkit Goyal" fue copiar y pegar desde http://code.google.com/p/android/issues/detail?id=3147 y el texto hace referencia a Donut. He reescrito este código varias veces desde entonces. Actualmente, en_US y la configuración regional predeterminada del sistema (en el momento del inicio) están en caché en el zygote. Existe un caché adicional por aplicación, por lo que para otras configuraciones locales solo debe pagar una vez.

El peor caso en las versiones modernas es cuando el usuario cambia la configuración regional predeterminada del sistema. Se requeriría un reinicio del zygote (un "reinicio en tiempo de ejecución" o un reinicio) para obtener las cadenas de zonas horarias de la nueva configuración predeterminada en caché en el zygote, donde podrían compartirse. (Describí este comportamiento en el comentario 11 sobre el error, y se envía con ICS.)

+0

Veo que estas instrucciones de registro suceden varias veces, después de cargar una fuente RSS con las bibliotecas HorrorRSS o ROME. No aparece cualquier cosa se almacena en caché, ya que las instrucciones de registro se imprimen cada vez que cargo un nuevo feed, incluso en el mismo método se llama una detrás de otra. Lo extraño es que no estoy usando SimpleDateFormat. Tengo una pregunta activa sobre esto en caso de que es curioso: http://stackoverflow.com/questions/12762 478/android-loaded-time-zone-names-for-en-in-ms –

Cuestiones relacionadas