我使用Android Studio 2.1.2和我的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)

我找了好几个小时才找到答案。答案来自于相关答案的组合,所以我想我会把我学到的东西记录下来,给其他可能在挣扎的人。看到答案。


当前回答

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

implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'

创建Application类并初始化它,如下所示:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

其他回答

注意:这个答案虽然在技术上是正确的,但现在已经过时了

Java 8+ API糖化支持现在可通过Android Gradle Plugin 4.0.0+

(参见下面Basil Bourque的回答)

ThreeTenABP库的开发正在逐步结束。请考虑切换到Android Gradle插件4.0,java.time。*,以及其核心库的糖化功能。

要在任何版本的Android平台上启用对这些语言api的支持,请将Android插件更新到4.0.0(或更高版本),并在模块的构建中包含以下内容。gradle文件:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}

原来的答案

第一个发现:为什么你必须使用ThreeTenABP而不是java。time, ThreeTen-Backport,甚至Joda-Time

这是定义新标准的一个非常漫长的过程的一个非常简短的版本。所有这些包几乎都是同一件事:为Java提供良好、现代的时间处理功能的库。这些差别虽然细微,但很重要。

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

然而,java。时间是在Java 8中引入的。Android直到Marshmallow都运行在Java 7上(“Android N”是引入Java 8语言特性的第一个版本)。因此,除非你只针对Android N Nougat及以上版本,否则你不能依赖Java 8语言的功能(我不确定这是100%正确的,但这是我的理解)。所以java。时间到了。

下一个选项可能是Joda-Time,因为JSR 310是基于Joda-Time的。然而,正如ThreeTenABP自述文件所指出的,出于许多原因,Joda-Time并不是最佳选择。

下一个是ThreeTen-Backport,它向后移植了大部分(但不是全部)Java 8 Java。Java 7的时间功能。这对于大多数用例来说都很好,但是,正如ThreeTenABP自述文中所指出的,它在Android上存在性能问题。

所以最后一个看似正确的选项是ThreeTenABP。

第二个发现:构建工具和依赖管理

由于编译程序(尤其是使用大量外部库的程序)非常复杂,Java几乎总是使用“构建工具”来管理这个过程。Make、Apache Ant、Apache Maven和Gradle都是与Java程序一起使用的构建工具(参见这篇文章进行比较)。如前所述,Gradle是Android项目的构建工具。

这些构建工具包括依赖项管理。Apache Maven似乎是第一个包含集中式包存储库的。Maven引入了Maven中央存储库,其功能相当于php的Packagist composer和Ruby的rubygems.org gem。换句话说,Maven中央存储库之于Maven(和Gradle),就像Packagist之于编写器——版本化包的权威和安全源。

第三个发现:Gradle处理Android项目中的依赖关系

High on my to-do list is to read the Gradle docs here, including their free eBooks. Had I read these weeks ago when I started learning Android, I would surely have known that Gradle can use the Maven Central Repository to manage dependencies in Android Projects. Furthermore, as detailed in this StackOverflow answer, as of Android Studio 0.8.9, Gradle uses Maven Central Repository implicitly through Bintray's JCenter, which means you don't have to do any extra config to set up the repo -- you just list the dependencies.

第四个发现:项目依赖项列在[项目目录]/app/build.gradle中

对于那些有在Java中使用Gradle经验的人来说,这是显而易见的,但我花了一段时间才弄明白。如果您看到有人说:“哦,只需添加编译'this-or-that.jar'”或类似的东西,就知道compile是该构建中的一个指令。指明编译时依赖项的Gradle文件。这是Gradle官方的依赖管理页面。

第五个发现:ThreeTenABP由Jake Wharton管理,而不是由ThreeTen管理

这是我花了太多时间想出来的另一个问题。如果您在Maven Central中查找ThreeTen,您将只看到threetenbp的包,而不是threetenabp。如果你去到ThreeTenABP的github repo,你会在Readme的下载部分看到臭名昭著的编译“this-or-that”行。

当我第一次碰到这个github回购,我不知道编译行意味着什么,我试图在我的终端上运行它(一个明显和可预测的失败)。我很沮丧,直到很长一段时间后我才回到它,最后意识到它是一个Maven Repo行指向com. jakewalton .threetenabp Repo,而不是org。threeten回购。这就是为什么我认为ThreeTenABP包不在Maven回购中。

总结:让它发挥作用

现在一切看起来都很简单。你可以在一个Android项目中获得现代的时间处理功能,确保你的[项目文件夹]/app/build。Gradle文件在它的依赖项部分有实现'com.jakewharton.threetenabp:threetenabp:1.2.1'行:

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'
}

也将这个添加到应用程序类:

public class App extends Application {    
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidThreeTen.init(this);
        //...
    }
}

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

implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'

创建Application类并初始化它,如下所示:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

凯尔接受的答案是正确的。此外,我将提到一些事情,并提供一个关于获取java的图表。时间的功能。

java。Android 26+内置时间

如果目标是Android 26或更高版本,你会发现JSR 310 (java。时间类)与Android捆绑。不需要添加ThreeTenABP。

api几乎相同

澄清一下,ThreeTenABP for Android是一个ThreeTen-Backport库的改编,它带来了大部分java。Java 6和Java 7的时间功能。这个后端端口与java.time共享几乎相同的API。

假设你现在的目标是26岁之前的Android,那么你使用ThreeTenABP。以后,你可能最终会放弃对这些早期版本的Android的支持,转而使用java。与Android捆绑的时间类。当这种情况发生时,除了(a)切换导入语句和(b)更改对org. threetenen .bp. datetimeutils的任何调用以使用添加到旧的遗留日期-时间类(Date, GregorianCalendar)的新转换方法外,您需要对代码库做一些更改。

从ThreeTenABP到java的过渡过程。时间应该是平稳的,几乎没有痛苦。

何时使用哪个框架

下面的图表显示了这三种框架,并指出了何时在哪些场景中使用哪种框架。

➥更新:Android Gradle Plugin 4.0.0+带来了一个新的第四个选项,API糖化,使可用的java的一个子集。时间功能不是最初内置在早期的Android。参见kael的主要答案的顶部。


关于java.time

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

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

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

从哪里获取java。时间类?

Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation. Java 9 brought some minor features and fixes. Java SE 6 and Java SE 7 Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport. Android Later versions of Android (26+) bundle implementations of the java.time classes. For earlier Android (<26), the process of API desugaring brings a subset of the java.time functionality not originally built into Android. If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….