在Android上使用Joda 1.6.2
以下代码挂起约15秒.
DateTime dt = new DateTime();
Run Code Online (Sandbox Code Playgroud)
最初发布这篇文章 Android Java - Joda Date在Eclipse/Emulator中很慢 -
刚试了一次它仍然没有更好.有没有其他人有这个问题或知道如何解决它?
plo*_*man 63
我也遇到了这个问题.Jon Skeet的怀疑是正确的,问题是时区的加载效率非常低,打开一个jar文件,然后读取清单试图获取这些信息.
但是,简单地调用DateTimeZone.setProvider([custom provider instance ...])是不够的,因为由于对我没有意义的原因,DateTimeZone有一个静态初始化器,它调用它getDefaultProvider().
为了完全安全,您可以通过在调用joda中的任何内容之前设置此系统属性来覆盖此默认值.
例如,在您的活动中添加以下内容:
@Override
public void onCreate(Bundle savedInstanceState) {
System.setProperty("org.joda.time.DateTimeZone.Provider",
"com.your.package.FastDateTimeZoneProvider");
}
Run Code Online (Sandbox Code Playgroud)
然后你所要做的就是定义FastDateTimeZoneProvider.我写了以下内容:
package com.your.package;
public class FastDateTimeZoneProvider implements Provider {
public static final Set<String> AVAILABLE_IDS = new HashSet<String>();
static {
AVAILABLE_IDS.addAll(Arrays.asList(TimeZone.getAvailableIDs()));
}
public DateTimeZone getZone(String id) {
if (id == null) {
return DateTimeZone.UTC;
}
TimeZone tz = TimeZone.getTimeZone(id);
if (tz == null) {
return DateTimeZone.UTC;
}
int rawOffset = tz.getRawOffset();
//sub-optimal. could be improved to only create a new Date every few minutes
if (tz.inDaylightTime(new Date())) {
rawOffset += tz.getDSTSavings();
}
return DateTimeZone.forOffsetMillis(rawOffset);
}
public Set getAvailableIDs() {
return AVAILABLE_IDS;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经测试了这个,它似乎适用于Android SDK 2.1+和joda版本1.6.2.它当然可以进一步优化,但在分析我的应用程序(mogwee)时,这会将 DateTimeZone初始化时间从~500ms减少到~18ms.
如果您使用proguard构建应用程序,则必须将此行添加到proguard.cfg,因为Joda希望类名完全按照您的指定:
-keep class com.your.package.FastDateTimeZoneProvider
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 23
我强烈怀疑这是因为它必须为默认时区建立ISO年表,这可能涉及读取所有时区信息.
你可以ISOChronology.getInstance()先通过调用,然后再调用一次来验证这一点new DateTime().我怀疑它会很快.
您知道哪些时区与您的申请相关吗?您可能会发现,通过使用非常简化的时区数据库重建Joda Time,您可以更快地完成整个过程.或者,DateTimeZone.setProvider()使用您自己的实现进行调用Provider,但不会执行任何工作.
这是值得检查是否这实际上是在第一个问题,当然:)你可能也想尝试明确地传递在UTC时区,这将不需要读取时区数据库...但你永远不知道你什么时候会无意中触发调用,它确实需要的默认时区,此时你会招致同样的成本.
Tyl*_*ier 10
我的应用程序中只需要UTC.所以,按照unchek的建议,我用了
System.setProperty("org.joda.time.DateTimeZone.Provider", "org.joda.time.tz.UTCProvider");
Run Code Online (Sandbox Code Playgroud)
org.joda.time.tz.UTCProvider实际上JodaTime使用它作为辅助备份,所以我想为什么不将它用作主要用途?到现在为止还挺好.它加载速度很快.
如果您必须为您的日期进行精确的时区计算,那么由plowman提供的最佳答案是不可靠的.以下是可能发生的问题示例:
假设您的DateTime对象设置为当天凌晨4点,即夏令时开始后一小时.当Joda FastDateTimeZoneProvider在凌晨3:00之前(即夏令时之前)检查提供者时,它将获得DateTimeZone具有错误偏移的对象,因为该tz.inDaylightTime(new Date())检查将返回false.
我的解决方案是采用最近发布的joda-time-android库.它使用Joda的核心,但确保仅根据需要从原始文件夹加载时区.使用gradle轻松设置.在您的项目中,扩展Application该类并在其上添加以下内容onCreate():
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
JodaTimeAndroid.init(this);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20678 次 |
| 最近记录: |