android - 如何在 Android 项目中使用 ThreeTenABP

标签 android datetime android-gradle-plugin threetenbp threetenabp

我问这个问题是因为我是 Java 和 Android 的新手,我搜索了几个小时试图解决这个问题。答案来自相关答案的组合,所以我想我会记录我所学到的东西,供其他可能遇到困难的人使用。见答案。

我使用的是 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)

最佳答案

注意:这个答案虽然在技术上是正确的,但现在已经过时了
Java 8+ API 脱糖支持现在可通过 Android Gradle Plugin 4.0.0+ 获得
(另见 Basil Bourque's answer below)
开发上ThreeTenABP Library正在收尾。请考虑在 future 几个月内改用 Android Gradle 插件 4.0、java.time.* 及其核心库脱糖功能。
要在任何版本的 Android 平台上启用对这些语言 API 的支持,请更新 Android plugin to 4.0.0 (or higher)并在模块的 build.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.time 包,因为这是在 Java 中处理时间和日期的新标准方法。它是 JSR 310 的实现,这是基于 Joda-Time 的时间处理新标准提案。图书馆。
然而,java.timeJava 8 中引入.安卓高达Marshmallow在 Java 7 上运行(“Android N”是第一个引入 Java 8 语言功能的版本)。因此,除非您只针对 Android N Nougat及以上,您不能依赖 Java 8 语言功能(我实际上不确定这是 100% 正确的,但我是这样理解的)。所以java.time出来了。
下一个选项可能是 Joda-Time , 自 JSR 310基于 Joda-Time。然而,作为ThreeTenABP readme表明,出于多种原因,Joda-Time 不是最佳选择。
接下来是 ThreeTen-Backport ,它向后移植了 Java 8 的大部分(但不是全部)java.time Java 7 的功能。这适用于大多数用例,但是,如 ThreeTenABP readme 所示,它在 Android 上存在性能问题。
所以最后一个看似正确的选项是 ThreeTenABP .
第二个发现:构建工具和依赖管理
由于编译程序——尤其是使用一堆外部库的程序——很复杂,Java 几乎总是使用 "build tool"来管理流程。 Make , Apache Ant , Apache Maven , 和 Gradle都是与 Java 程序一起使用的构建工具(参见 this post 进行比较)。如下所述,Gradle 是 Android 项目的首选构建工具。
这些构建工具包括依赖管理。 Apache Maven 似乎是第一个包含集中式包存储库的。 Maven 推出了 Maven Central Repository ,它允许的功能等同于 php 的 composer与 Packagist 和 Ruby 的 gem与 ruby​​gems.org。换句话说,Maven Central Repository 之于 Maven(和 Gradle)就像 Packagist 之于 Composer ——版本化包的权威和安全来源。
第三个发现:Gradle 处理 Android 项目中的依赖
我的待办事项列表中最重要的是阅读 Gradle 文档 here ,包括他们的免费电子书。如果我在这几周前开始学习 Android 时阅读了这些内容,我肯定会知道 Gradle 可以使用 Maven 中央存储库来管理 Android 项目中的依赖项。此外,如 this 中所述StackOverflow 回答,从 Android Studio 0.8.9 开始,Gradle 通过 Bintray 的 JCenter 隐式使用 Maven 中央存储库,这意味着您无需进行任何额外的配置来设置存储库——您只需列出依赖项。
第四发现:项目依赖在[project dir]/app/build.gradle中列出
同样,对于那些在 Java 中使用 Gradle 有任何经验的人来说很明显,但我花了一段时间才弄清楚这一点。如果您看到人们说“哦,只需添加 compile 'this-or-that.jar'”或类似的话,请知道 compile是该 build.gradle 文件中的一个指示编译时依赖项的指令。 Here's关于依赖管理的官方 Gradle 页面。
第五发现:ThreeTenABP 由 jack 沃顿管理,而不是由 ThreeTen 管理
还有一个问题我花了太多时间弄明白。如果您在 Maven Central 中查找 ThreeTen,您将只会看到 threetenbp 的包,不是 threetenabp .如果你去github repo for ThreeTenABP ,你会看到臭名昭著的 compile 'this-or-that'自述文件的下载部分下的行。
当我第一次点击这个 github repo 时,我不知道那条编译行是什么意思,我试图在我的终端中运行它(明显且可预测的失败)。很沮丧,直到我想通了其余部分后很久才回到它,最终意识到这是一条指向 com.jakewharton.threetenabp 的 Maven Repo 行。 repo ,而不是 org.threeten repo 。这就是为什么我认为 ThreeTenABP 包不在 Maven 仓库中的原因。
总结:让它发挥作用
现在这一切似乎很容易。您可以通过确保您的 [project folder]/app/build.gradle 在 Android 项目中获得现代时间处理功能。文件有 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);
        //...
    }
}

关于android - 如何在 Android 项目中使用 ThreeTenABP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38922754/

相关文章:

android - 使用相机时如何打开/关闭手电筒?

python - Pyspark - 将 mmddyy 转换为 YYYY-MM-DD

php - 如何使用 **TIME ZONE** 将 NSDate 存储到 DATETIME?

使用 Visa QRParser-2.2.0 和 minSdkVersion 19 的 Android 构建失败(transformClassesWithDesugar)

java-native-interface - 在设备上找不到 Gradle native 库,但存在于 apk 中

android - 根据buildType更改android项目中的.properties文件和settings.gradle文件

c# - 无法加载类型 'System.Net.Http.FormattingUtilities'

java - 当新的应用程序实例启动时,如何将数据传递给已经运行的应用程序实例

android - 使用嵌套 ScrollView 问题的响应式设计

来自 12 小时格式日期和时间字符串的 JavaScript 新日期