注意:这个答案虽然在技术上是正确的,但现在已经过时了
Java 8+ API 脱糖支持现已通过 Android Gradle 插件 4.0.0+ 提供
(另请参阅Basil Bourque 的回答如下)
发展于ThreeTenABP 库正在结束。请考虑在未来几个月内切换到 Android Gradle 插件 4.0、java.time.* 及其核心库脱糖功能。
要在任何版本的 Android 平台上启用对这些语言 API 的支持,请将 Android 插件更新到 4.0.0(或更高版本),并在模块的 build.gradle 文件中包含以下内容(来自Android 开发者网站上 Java 8 支持页面的这一部分,其中还有有关脱糖的附加信息):
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'
}
原答案
第一个发现:为什么你必须使用三十ABP代替java.time, 三十后端口, 甚至乔达时间
这是定义新标准的漫长过程的一个非常简短的版本。所有这些包几乎都是一样的:为 Java 提供良好的、现代的时间处理功能的库。差异很微妙但很重要。
最明显的解决方案是使用内置的java.time包,因为这是 Java 中处理时间和日期的新标准方法。它是一个实现JSR 310,这是一个基于时间处理的新标准提案乔达时间图书馆。
然而,java.time
被介绍于Java 8。安卓高达棉花糖在 Java 7 上运行(“Android N”是第一个引入 Java 8 语言功能的版本)。因此,除非你的目标只是安卓NNougat及以上,你不能依赖 Java 8 语言功能(我实际上不确定这是否 100% 正确,但这就是我的理解)。所以java.time
is out.
下一个选择可能是乔达时间, since JSR 310基于 Joda-Time。然而,作为ThreeTenABP 自述文件表明,出于多种原因,Joda-Time 不是最佳选择。
Next is 三十后端口,向后移植了 Java 8 的大部分(但不是全部)java.time
Java 7 的功能。这对于大多数用例来说都很好,但是,如ThreeTenABP 自述文件,它与 Android 存在性能问题。
所以最后一个看似正确的选项是三十ABP.
第二个发现:构建工具和依赖管理
由于编译程序(尤其是使用一堆外部库的程序)很复杂,因此 Java 几乎总是使用“构建工具”来管理流程。Make, 阿帕奇蚂蚁, 阿帕奇Maven, and Gradle都是与 Java 程序一起使用的构建工具(请参阅这个帖子用于比较)。正如下文所述,Gradle 是 Android 项目选择的构建工具。
这些构建工具包括依赖管理。 Apache Maven 似乎是第一个包含集中式包存储库的。 Maven 介绍了Maven 中央存储库,它允许与 php 等效的功能composer
与 Packagist 和 Ruby 合作gem
与 rubygems.org。换句话说,Maven 中央存储库之于 Maven(和 Gradle)就像 Packagist 之于 Composer —— 版本化包的明确且安全的来源。
第三个发现:Gradle 处理 Android 项目中的依赖关系
我的待办事项清单中最重要的是阅读 Gradle 文档here,包括他们的免费电子书。如果我几周前开始学习 Android 时读过这些内容,我肯定会知道 Gradle 可以使用 Maven 中央存储库来管理 Android 项目中的依赖项。此外,正如详细介绍的thisStackOverflow 的回答是,从 Android Studio 0.8.9 开始,Gradle 通过 Bintray 的 JCenter 隐式使用 Maven Central Repository,这意味着您无需执行任何额外的配置来设置存储库 - 您只需列出依赖项。
第四个发现:项目依赖项列在 [project dir]/app/build.gradle 中
同样,对于那些有 Java 使用 Gradle 经验的人来说这是显而易见的,但我花了一段时间才弄清楚这一点。如果你看到人们说“哦,只需添加compile 'this-or-that.jar'
“或类似的东西,知道compile
是 build.gradle 文件中的一个指令,指示编译时依赖项。Here's有关依赖管理的官方 Gradle 页面。
第五个发现:ThreeTenABP 由 Jake Wharton 管理,而不是 ThreeTen
还有一个问题我花了太多时间来解决。如果您在 Maven Central 中查找 ThreeTen,您只会看到以下包threetenbp
, not threetenabp
。如果你去ThreeTenABP 的 github 存储库,你会看到那个臭名昭著的compile 'this-or-that'
自述文件下载部分下的行。
当我第一次访问这个 github 存储库时,我不知道该编译行意味着什么,我尝试在我的终端中运行它(出现明显且可预测的失败)。沮丧的是,我直到弄清楚其余部分很久之后才返回它,并最终意识到这是一条指向 Maven Repo 的行com.jakewharton.threetenabp
回购协议,而不是org.threeten
回购。这就是为什么我认为 Maven 存储库中没有 ThreeTenABP 包。
摘要:让它发挥作用
现在一切看起来都很简单。您可以通过确保您的 Android 项目获得现代时间处理功能[project folder]/app/build.gradle
文件有implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
线在其dependencies
部分:
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'
}
还将其添加到 Application 类中:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
AndroidThreeTen.init(this);
//...
}
}