我使用的是这个简单的日期格式
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毫秒。。。
以前有人有这个问题吗?
这是由于时区字符串的延迟初始化造成的。只有第一个打电话要花这么长时间。如果此后再次使用SimpleDateFormat,则从缓存加载,应该不会再花那么长时间了。
在更改之前,它是在加载类时完成的,因此一项活动要多花2-3秒。这对用户的影响要严重得多比第一次实际使用时花费的那几秒钟更有经验。这个问题是,由于设计的原因,现在没有办法绕过这个问题SimpleDateFormat api的。只有速度更快的手机才能通过减少花费来解决这个问题是时候收集那些字符串了。
缓存发生在SimpleDateFormat正在使用的DateFormatSymbols中。通过重用该实例,可能只需要加载一次sting(对于相同的泥鳅)。您也可以在启动时在线程中创建该实例活动,使其在使用后已缓存。要初始化字符串,只需调用.hashCode(),它强制初始化缓存。稍微快一点,但不那么简单将序列化实例。这也会强制对缓存进行初始化。
在此期间,请考虑在需要SimpleDateFormat之前使用AsyncTask在流程中"预热"它。只需在AsyncTask doInBackground()中解析一些日期,让它在不会对用户产生太大影响的时候加载时区。一旦在您的流程中初始化,SimpleDateFormat将快速运行,直到您的流程终止。
这在最近的Android版本上是不正确的(从日志消息的文本中,我可以看出你运行的是旧版本;现代版本告诉你在icu4c和托管代码上花了多少时间)。请注意,"Pulkit Goyal"的答案是从http://code.google.com/p/android/issues/detail?id=3147文本指的是甜甜圈。从那以后,我已经多次重写了这段代码。目前,en_US和系统的默认区域设置(在启动时)缓存在合子中。还有一个针对每个应用程序的缓存,因此对于其他地区,您只需支付一次。
现代版本中最糟糕的情况是用户更改系统的默认区域设置。它需要重新启动合子("运行时重新启动"或重新启动),才能将新的默认区域设置的时区字符串缓存在可以共享的合子中。(我在关于bug的注释11中描述了这种行为,它与ICS一起提供。)