如何在Android项目中使用ThreeTenABP

2023-11-27

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

I searched for hours trying to figure this out. The answer came from a combination of related answers, so I figured I would document what I learned for anyone else who may be struggling. See answer.


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

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.timeJava 7 的功能。这对于大多数用例来说都很好,但是,如ThreeTenABP 自述文件,它与 Android 存在性能问题。

所以最后一个看似正确的选项是三十ABP.

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

由于编译程序(尤其是使用一堆外部库的程序)很复杂,因此 Java 几乎总是使用“构建工具”来管理流程。Make, 阿帕奇蚂蚁, 阿帕奇Maven, and Gradle都是与 Java 程序一起使用的构建工具(请参阅这个帖子用于比较)。正如下文所述,Gradle 是 Android 项目选择的构建工具。

这些构建工具包括依赖管理。 Apache Maven 似乎是第一个包含集中式包存储库的。 Maven 介绍了Maven 中央存储库,它允许与 php 等效的功能composer与 Packagist 和 Ruby 合作gem与 ruby​​gems.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);
        //...
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Android项目中使用ThreeTenABP 的相关文章

  • 如何更改Appcompat主题中的TimePicker线条颜色?

    如何更改 Appcompat 主题中所选数字之间的 TimePicker 线条颜色 线条是蓝色的 但我需要橙色线条 我将 TimePickerDialog 与 ContextThemeWrapper 一起使用 TimePickerDialo
  • 有没有办法隐藏 TextView 中的文本?

    有没有办法隐藏 TextView 中的部分 但不是全部 文本 我尝试使用 AbsoluteSizeSpan 将大小设置为 0 但这没有任何我看到的视觉效果 你可以将大小设置为 1 但实际上你会得到凹凸不平的线条 而不是可读的文本 很可爱 但
  • Fused Location Provider 是不错的选择吗?

    我正在开发一个应用程序 我想在其中使用融合位置提供程序 但我有一些疑问 还有几个问题 当 GPS 关闭并且我将优先级设置为 HIGH 时 是否意味着 GPS 会自动打开 我可以根据需要将 UpdateLocation 设置为具有高优先级的
  • FCM:无法实例化接收器 com.google.firebase.iid.FirebaseInstanceIdReceiver:

    仅在 Oreo 8 0 中接收推送通知时应用程序崩溃 java lang RuntimeException Unable to instantiate receiver com google firebase iid FirebaseIns
  • Mediaplayer 播放几次后停止播放

    我有一个按钮 按下它会播放一个随机声音剪辑 然后播放另一个声音剪辑 然后通过一个媒体播放器播放另一个声音剪辑 但是多次按下该按钮 15 20 次 后 所有音频都会停止 我在播放最后一个音频剪辑后释放媒体播放器 所以我不认为这是原因 有什么指
  • onScale 和 Canvas - 缩放图像后如何调整原点?

    我有一个非常简单的测试应用程序 带有自定义组件MyView java https github com afarber android newbie blob master TestScroll src de afarber testscr
  • 如何在android中使用retrofit访问404错误?

    我正在使用改造 2 访问 REST API 以使用原始正文插入 JSON 数据 我从服务器获得成功响应 但在响应时收到 404 错误 我想访问404错误请帮我解决这个问题 ApiUtil getServiceClass sendFinalC
  • 将网页保存到android中的webview缓存中

    我正在创建一个应用程序 它将从互联网下载一些网页 并在用户单击按钮时将它们保存到缓存 并在没有互联网可用时加载它们 当我运行代码时 出现空指针异常 我已在清单文件中添加了所有必要的权限 public class MainActivity e
  • 如何在android中以编程方式自动执行触摸

    我有一个RelativeLayout我想在不触摸屏幕的情况下执行触摸事件想要给出Toast如果它确实被触摸或没有被触摸 请抛出消息 我已经尝试过下面的方法 但它似乎不起作用 MotionEvent event MotionEvent obt
  • Android 闹钟应用程序在 Oreo 下因 NullPointerException 导致 SystemUI 崩溃(仅限)

    我有一个 Android 闹钟应用程序 我有通常的 警报意图 gt 接收器 gt 活动链 其最后一步创建一个全屏窗口并发出警报 所有这些在 Oreo API 26 之前的 Android 版本上都可以正常工作 但在 Oreo 上 当警报触发
  • 将可渲染节点(相同的旋转、位置和比例)替换为 Sceneform sdk 中的另一个可渲染节点

    我是 Android 版 sceneform sdk 的新手 我已经添加了一个Transformable Node 然后我应用了一些旋转 缩放并改变了它的位置 现在 单击按钮后 我需要放置具有相同旋转 缩放和位置的第二个节点 为此我所做的是
  • TabHost 中的 Webview = 以黑屏启动

    我正在尝试在有 4 个选项卡的 tabhost 中使用 webview 所有选项卡都链接到同一个 webview 这很好 除了一个问题 启动时 网络视图是黑色的 单击选项卡 2 3 或 4 使其 活跃起来 我的快速解决方法是使用 setCu
  • Android 中表与游标的并集

    我正在尝试将两个具有相同字段的表合并起来 通过内容提供程序 创建一个用于创建 ListView 的游标 Override public Cursor query Uri uri String projection String select
  • 如何在应用程序中创建会话对象

    在我的应用程序中 我想创建一个用于登录和注销的会话 我不知道如何使用会话 任何人都可以通过提供一些示例来帮助我 我认为会话对象应该是在应用程序开始运行时声明和初始化的静态对象 我遇到了这个问题 并决定将我的会话对象放入 utils 类中 该
  • 在 Android 运行时更改和应用主题 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在 Android 运行时更改当前主题 https stackoverflow com questions 2482848 how to change current theme at runti
  • Gradle创建多项目Jar

    因此 从 Gradle 和 Android Studio 诞生之初起 我就一直在使用它们 然而 我发现自己用头撞墙的次数有时远远超过了它的价值 我花了一天半的时间试图解决我目前的困境 在我工作的地方 我们使用很多共享库项目 这意味着与 Gr
  • 短信管理器在少于 160 个字符时发送多部分消息

    我编写了一个使用短信管理器的应用程序 我用的方法sendTextMessage 但这行不通 现在我正在使用sendMutlipartTextMessage 这是工作 但当它大约 60 个字符时 它会发送多部分消息 这个是正常的 我读过的所有
  • 如何为移动应用程序创建无密码登录

    我有兴趣在移动应用程序和 API 之间构建某种无密码登录 假设我可以控制两者 动机是必须登录对用户来说非常烦人并且存在安全风险 例如 用户将重复使用现有密码 我希望用户能够立即开始使用该应用程序 我想知道是否有一些可行的技术 例如 在移动设
  • 是否可以在本机代码中读取/编辑共享首选项?

    我有一个 Android 应用程序 其中包含一个使用 NDK 执行一些代码的 C 库 在 C 库中 我想更新应用程序共享首选项 我的问题 是否可以在本机代码中读取 编辑共享首选项 您可以在本机代码中做任何您想做的事情 这只是很麻烦 您需要
  • Jetpack 中的波浪框组成

    有没有办法用Canvas制作一个顶部有波浪形的盒子 我想知道这个效果是否可以直接用Canvas来实现 不需要有滚动动画 不太清楚你为什么在谈论Canvas 要裁剪这样的视图 您可以使用自定义Shape并将其应用到您的视图中Modifier

随机推荐