如何在Android Project中使用ThreeTenABP

kae*_*ael 169 datetime android android-gradle-plugin threetenbp threetenabp

我正在添加这个问题,因为我是Java和Android的新手,我搜索了几个小时试图解决这个问题.答案来自相关答案的组合,所以我想我会记录我为其他可能正在努力的人学到的东西.见答案.

对于一些背景知识,我的经验主要是PHP的Web开发和一点Ruby.我唯一的操作系统是Linux(Ubuntu Studio),我(不情愿地)在Android Studio 2.1.2中开发我的第一个Android应用程序.我的Java设置如下:

>java -version
> openjdk version "1.8.0_91"
> OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~15.10.1-b14)
> OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)
Run Code Online (Sandbox Code Playgroud)

kae*_*ael 164

First Discovery:为什么你必须使用ThreeTenABP而不是java.time,ThreeTen- Backport,甚至是Joda-Time

这是定义新标准的非常长的过程的一个非常简短的版本.所有这些包几乎都是一样的:为Java提供良好,现代的时间处理功能的库.差异很微妙但很重要.

最明显的解决方案是使用内置java.time包,因为这是处理Java中时间和日期的新标准方法.它是JSR 310的一个实现,它是基于Joda-Time库的时间处理的新标准提议.

但是,java.timeJava 8中引入了.Android版Marshmallow在Java 7上运行("Android N"是第一个引入Java 8语言功能的版本).因此,除非你只针对Android N Nougat及以上,否则你不能依赖Java 8语言功能(我实际上并不确定这是100%真实,但这是我理解它的方式).好java.time了.

下一个选项可能是Joda-Time,因为JSR 310基于Joda-Time.但是,正如ThreeTenABP自述文件所示,由于多种原因,Joda-Time不是最好的选择.

接下来是ThreeTen-Backport,它将Java 8 java.time功能的大部分(但不是全部)反向移植到Java 7.这对于大多数用例来说都很好,但是,正如ThreeTenABP自述文件所示,它在Android上存在性能问题.

所以最后看似正确的选项是ThreeTenABP.

第二次发现:构建工具和依赖关系管理

由于编译程序 - 特别是使用一堆外部库的程序 - 很复杂,因此Java几乎总是使用"构建工具"来管理该过程.Make,Apache Ant,Apache MavenGradle都是与Java程序一起使用的构建工具(请参阅此文章进行比较).如下所述,Gradle是Android项目的选择构建工具.

这些构建工具包括依赖项管理.Apache Maven似乎是第一个包含集中式软件包存储库的人.Maven引入了Maven Central Repository,它允许composer使用与Packagist和Ruby的Ruby相同的功能,gem使用rubygems.org.换句话说,Maven Central Repository是Maven(和Gradle)Packagist的作曲家 - 一个版权化软件包的权威和安全来源.

第三次发现:Gradle处理Android项目中的依赖项

高我的待办事项清单上是阅读文档摇篮这里,包括他们的免费电子书.如果我几周前开始学习Android时读过这篇文章,我肯定知道Gradle可以使用Maven Central Repository来管理Android项目中的依赖项.此外,正如此 StackOverflow答案中详细说明的那样,从Android Studio 0.8.9开始,Gradle通过Bintray的JCenter隐式使用Maven Central Repository,这意味着您无需进行任何额外的配置来设置repo - 您只需列出依赖.

第四次发现:项目依赖项列在[project dir] /app/build.gradle中

对于那些在Java中使用Gradle有经验的人来说,显而易见,但我花了一些时间才弄清楚这一点.如果你看到人们说"哦,只是添加compile 'this-or-that.jar'"或类似的东西,知道这compile是build.gradle文件中的一个指令,它指示编译时依赖性.这是依赖关系管理的官方Gradle页面.

第五次发现:ThreeTenABP由杰克沃顿管理,而不是由ThreeTen管理

还有一个问题我花了太多时间搞清楚.如果您在Maven Central中寻找ThreeTen,您只会看到包裹threetenbp,而不是threetenabp.如果你去了ThreeTenABPgithub仓库,你会compile 'this-or-that'在自述文件的下载部分看到臭名昭着的行.

当我第一次点击这个github repo时,我不知道编译行是什么意思,我试图在我的终端中运行它(具有明显且可预测的失败).沮丧,直到我想出其余部分之后我才回到它身上,最后意识到这是一个指向com.jakewharton.threetenabp回购的Maven回购线,而不是org.threeten回购.这就是为什么我认为ThreeTenABP软件包不在Maven回购中.

总结:让它发挥作用

现在一切看起来都很简单.您可以通过确保您的[project folder]/app/build.gradle文件implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'在其dependencies部分中包含以下行来获取Android项目中的现代时间处理函数:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "me.ahuman.myapp"
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:23.4.0'
    implementation 'com.android.support:design:23.4.0'
    implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
}
Run Code Online (Sandbox Code Playgroud)

  • 确保在使用API​​之前先调用`AndroidThreeTen.init(this)`,例如在onCreate()中。请参阅[Android上的ThreeTen-Backport错误-ZoneRulesException:未注册时区数据文件](https:// stackoverflow.com/questions/38281808/threeten-backport-error-on-android-zonerulesexception-no-time-zone-data-files)。 (5认同)
  • @ Bob,JodaTime与JSR-310基本相同(甚至基本上由同一个人制造),只是JSR-310的设计缺陷较少(请参阅[本文](http://blog.joda.org/2009/例如11 / why-jsr-310-isn-joda-time_4941.html)。[...下续] (2认同)
  • 为了澄清评论...... [*java.time*](https://docs.oracle.com/javase/9​​/docs/api/java/time/package-summary.html) 框架 ([JSR 310](https ://jcp.org/en/jsr/detail?id=310)) 是 [*Joda-Time*](http://www.joda.org/joda-time/) 项目的官方继承者。这两个项目都由同一个人 [Stephen Colebourne](/sf/users/2722751/) 领导。Joda-Time 项目现在处于维护模式,团队建议迁移到 java.time。 (2认同)

Bas*_*que 12

kael接受的答案是正确的。此外,我将提及一些事情,并提供有关获取java.time功能的图表。

java.time内置于 Android 26+

如果面向Android 26或更高版本,您会发现与 Android 捆绑在一起的JSR 310java.time类)的实现。无需添加ThreeTenABP

API 几乎相同

澄清一下,Android 版ThreeTenABPThreeTen-Backport库的改编版,它将大部分java.time功能带到了Java 6Java 7 中。这个后向端口与java.time共享几乎相同的 API 。

假设您现在的目标是早于 26 的 Android,因此您使用ThreeTenABP。稍后,您可能最终会放弃对这些早期版本的 Android 的支持,以使用与 Android 捆绑在一起的java.time类。发生这种情况时,除了 (a) 切换import语句和 (b) 更改您所做的任何调用org.threeten.bp.DateTimeUtils以使用添加到旧的遗留日期时间类 ( Date, GregorianCalendar) .

ThreeTenABPjava.time的过渡过程应该是平稳且几乎无痛的。

何时使用哪个框架

这是显示三个框架的图表,并指示何时在哪些场景中使用哪个框架。

? 更新: Android Gradle 插件 4.0.0+ 带来了新的第四个选项,API 脱糖,以提供最初未内置于早期 Android 中java.time功能子集。请参阅kael的主要答案的顶部。

哪个 java.time 库与哪个版本的 Java 或 Android 一起使用的表


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。Hibernate 5 & JPA 2.2 支持java.timejava.sql.*

从哪里获得 java.time 类?


Ric*_*ere 6

在 Android Studio 的构建 gradle(模块级别)文件中添加以下内容:

implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
Run Code Online (Sandbox Code Playgroud)

创建 Application 类并像这样初始化它:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}
Run Code Online (Sandbox Code Playgroud)