包含时区时,SimpleDateFormat需要太长时间

时间:2012-01-16 14:06:51

标签: android datetime timezone delay simpledateformat

我正在使用这种简单的日期格式

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

问题是当我使用它时转换时间需要太长时间,在logcat中我看到这样的东西

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.

我如何使用简单的日期格式化程序,但为了加快速度,我不想每次转换需要大约150毫秒......

以前有人遇到过这个问题吗?

2 个答案:

答案 0 :(得分:10)

这是由于时区区域字符串的延迟初始化造成的。只有第一个 电话会花这么久。如果之后再次使用SimpleDateFormat 从缓存加载,不应再花那么长时间了。

在更改之前,它已在类加载时完成,从而开始了 一项活动花了2-3秒的时间。这对用户的影响要大得多 经验比在第一次实际使用时需要几秒钟。该 问题是由于设计原因现在无法绕过这个问题 SimpleDateFormat api。只有速度更快的手机可以通过减少费用来解决这 收集这些字符串的时间。

缓存发生在SimpleDateFormat正在使用的DateFormatSymbols中。通过 重用那个实例,可能只需要加载一次蜇(对于 同样的事情)。您还可以在启动时在线程中创建该实例 活动,以便它一旦被使用就已经缓存。要初始化字符串只需调用 .hashCode()强制初始化缓存。会更快但不那么简单 是序列化实例。这也会强制缓存初始化。

在此期间,请考虑在需要之前使用AsyncTask在您的流程中“预热”SimpleDateFormat。只需在AsyncTask doInBackground()中解析一些日期,以便在不会对用户造成太大影响的情况下加载时区。在您的流程中初始化后,SimpleDateFormat将快速运行,直到您的流程终止。

答案 1 :(得分:4)

在Android的最新版本中并非如此(从日志消息的文本我可以看出你正在运行一个旧版本;现代版本告诉你在icu4c和托管代码上花了多少时间)。请注意,“Pulkit Goyal”的答案是从http://code.google.com/p/android/issues/detail?id=3147复制并粘贴,文字是指 Donut 。从那时起,我已多次重写此代码。目前,en_US和系统的默认语言环境(在引导时)被缓存在受精卵中。还有一个每个应用程序缓存,因此对于其他语言环境,您只需支付一次。

现代版本中最糟糕的情况是用户更改系统的默认区域设置。这将需要重启zygote(“运行时重启”或重启)以获取新的默认语言环境的时区字符串缓存在合子中,它们可以共享。 (我在关于错误的评论11中描述了这种行为,它随ICS一起提供。)