2016-07-09 54 views
14

我为我的Android项目使用ThreeTen-Backport库(因为java.time还未在android开发中实现)。Android上的ThreeTen-Backport错误 - ZoneRulesException:没有注册时区数据文件

当我写LocalDate today=LocalDate.now();LocalTime time=LocalTime.now();我得到以下异常:

Caused by: org.threeten.bp.zone.ZoneRulesException: 
    No time-zone data files registered 
     at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:176) 
     at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:133) 
     at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143) 
     at org.threeten.bp.ZoneId.of(ZoneId.java:357) 
     at org.threeten.bp.ZoneId.of(ZoneId.java:285) 
     at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:244) 
     at org.threeten.bp.Clock.systemDefaultZone(Clock.java:137) 
     at org.threeten.bp.LocalDate.now(LocalDate.java:165) 

相同的代码行效果很好另一个Java项目,我有,它使用本地java.time库。

我搜索了一个可能的解决方案,但找不到任何有用的东西:一个解决方案建议我需要使用另一个包含时区规则的jar,其他jar提示在classpath中可能有两个或多个ThreeTenBP库。
这些情况与我的情况不符。

里面的build.gradle文件,在依赖关系部分,我试过几个配置:

  • 起初,我用 - compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'
  • 然后,我尝试 - compile 'org.threeten:threetenbp:1.0.3'
  • 之后,我试过 - compile 'org.threeten:threetenbp:1.3.1'
  • 目前,我用compile 'org.threeten:threetenbp:1.3.2'

我不知道这行代码有什么问题,以及如何解决它。
LocalDate.now()LocalTime.now()方法应该没有指定时区的工作。

回答

24

对于Android项目,你应该使用

compile 'com.jakewharton.threetenabp:threetenabp:1.0.3 

确保您使用从库中的类之前调用​​AndroidThreeTen.init(this);。这将读取时区数据(包含在库中)。您可以在onCreate方法中对Application类中的库进行初始化,就像在README中推荐的那样。

+2

谢谢,我的项目之前没有应用程序类,所以我无法使用'AndroidThreeTen.init(this)''代码。我想在活动的'onCreate'方法中加入这个,但是我看到它不正确。 现在我创建了一个新的类,它扩展了应用程序类并将该行放入'onCreate'方法中。现在一切正常! –

+1

在onCreate中调用init违反了strictmode,甚至可能会延迟应用程序启动。如果您异步调用init,则必须确保在完成之前不要使用它,这对于JUnit测试来说很难。 –

+4

@ErikB它确实违反了严格模式,因为它从资产中读取时区文件,因此延迟了启动时间。对于单元测试,你应该使用原始库http://www.threeten.org/threetenbp/,因为这里有Android依赖关系,如https://github.com/JakeWharton/ThreeTenABP/issues/14 – LordRaydenMK