Как использовать ThreeTenABP в Android Project

Aug 13 2016

Я задаю этот вопрос, потому что я новичок в 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)

Ответы

200 kael Aug 12 2016 at 23:36

Внимание: этот ответ, хотя и верный с технической точки зрения, теперь устарел.

Поддержка удаления сахара из API Java 8+ теперь доступна через плагин Android Gradle 4.0.0+

(Также см . Ответ Базиля Бурка ниже )

Разработка библиотеки ThreeTenABP сворачивается. В ближайшие месяцы рассмотрите возможность перехода на подключаемый модуль Android Gradle 4.0, java.time. * И его функцию удаления шугаринга основной библиотеки.

Чтобы включить поддержку этих языковых API в любой версии платформы Android, обновите плагин Android до 4.0.0 (или выше) и включите следующее в файл 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.timeбыл представлен в Java 8 . Android до Marshmallow работает на Java 7 («Android N» - первая версия, в которой представлены функции языка Java 8). Таким образом, если вы не ориентируетесь только на Android N Nougat и выше, вы не можете полагаться на функции языка Java 8 (на самом деле я не уверен, что это на 100% верно, но я так понимаю). Так java.timeвышло.

Следующим вариантом может быть Joda-Time , поскольку JSR 310 был основан на Joda-Time. Однако, как показывает файл Readme ThreeTenABP , по ряду причин Joda-Time - не лучший вариант.

Далее идет ThreeTen-Backport , который переносит большую часть (но не все) функциональности Java 8 java.timeна Java 7. Это нормально для большинства случаев использования, но, как указано в файле Readme ThreeTenABP , у него есть проблемы с производительностью с Android.

Итак, последний и, казалось бы, правильный вариант - ThreeTenABP .

Второе открытие: инструменты сборки и управление зависимостями

Поскольку компиляция программы - особенно с использованием набора внешних библиотек - сложна, Java почти всегда использует «инструмент сборки» для управления процессом. Make , Apache Ant , Apache Maven и Gradle - все это инструменты сборки, которые используются с программами Java (см. Этот пост для сравнения). Как отмечено ниже, Gradle - это выбранный инструмент сборки для проектов Android.

Эти инструменты сборки включают управление зависимостями. Apache Maven, кажется, первым включает централизованный репозиторий пакетов. Maven представил центральный репозиторий Maven , который обеспечивает функциональность, эквивалентную php composerс Packagist и Ruby gemс rubygems.org. Другими словами, центральный репозиторий Maven для Maven (и Gradle) - это то же самое, что Packagist для композитора - окончательный и безопасный источник для версий пакетов.

Третье открытие: Gradle обрабатывает зависимости в проектах Android

В моем списке дел стоит прочитать здесь документы Gradle , в том числе их бесплатные электронные книги. Если бы я прочитал эти недели назад, когда начал изучать Android, я бы наверняка знал, что Gradle может использовать Maven Central Repository для управления зависимостями в проектах Android. Кроме того, как подробно описано в этом ответе StackOverflow, начиная с Android Studio 0.8.9, Gradle использует центральный репозиторий Maven неявно через JCenter Bintray, что означает, что вам не нужно делать дополнительную конфигурацию для настройки репо - вы просто указываете зависимости.

Четвертое открытие: зависимости проекта перечислены в [каталог проекта] /app/build.gradle

Опять же, это очевидно для тех, у кого есть опыт использования Gradle на Java, но мне потребовалось время, чтобы понять это. Если вы видите людей, говорящих «О, просто добавьте compile 'this-or-that.jar'» или что-то подобное, знайте, что compileэто директива в файле build.gradle, которая указывает зависимости во время компиляции. Вот официальная страница Gradle по управлению зависимостями.

Пятое открытие: ThreeTenABP управляет Джейк Уортон, а не ThreeTen

Еще одна проблема, над решением которой я потратил слишком много времени. Если вы поищете ThreeTen в Maven Central, вы увидите только пакеты для threetenbp, но не для threetenabp. Если вы перейдете в репозиторий на github для ThreeTenABP , вы увидите эту печально известную compile 'this-or-that'строку в разделе «Загрузить» файла Readme.

Когда я впервые попал в репозиторий github, я не знал, что означает эта строка компиляции, и попытался запустить ее в своем терминале (с очевидной и предсказуемой ошибкой). Разочарованный, я не возвращался к нему, пока не понял все остальное и наконец понял, что это строка Maven Repo, указывающая на com.jakewharton.threetenabpрепо, а не на org.threetenрепо. Вот почему я подумал, что пакета ThreeTenABP нет в репозитории Maven.

Резюме: заставить его работать

Теперь все кажется довольно простым. Вы можете получить современные функции обработки времени в 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'
}

Также добавьте это в класс приложения:

public class App extends Application {    
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidThreeTen.init(this);
        //...
    }
}
8 BasilBourque May 05 2020 at 07:35

Принятый ответ Каэля верен. Кроме того, я упомяну пару вещей и представлю схему получения функциональности java.time .

java.time встроен в Android 26+

Если вы ориентируетесь на Android 26 или более позднюю версию , вы найдете реализацию JSR 310 ( классы java.time ) в комплекте с Android. Не нужно добавлять ThreeTenABP .

API почти идентичны

Чтобы уточнить, ThreeTenABP для Android - это адаптация библиотеки ThreeTen-Backport, которая обеспечивает большую часть функциональности java.time для Java 6 и Java 7 . Этот задний порт имеет почти идентичный API с java.time .

Предположим, вы теперь ориентируетесь на Android ранее, чем 26, поэтому вы используете ThreeTenABP . Позже вы можете в конечном итоге отказаться от поддержки этих более ранних версий Android, чтобы использовать классы java.time в комплекте с Android. Когда это произойдет, вам нужно внести несколько изменений в свою кодовую базу, кроме (а) importоператоров переключения и (б) изменения любых вызовов, которые вы сделали, org.threeten.bp.DateTimeUtilsчтобы использовать новые методы преобразования, которые были добавлены в старые устаревшие классы даты и времени ( Date, GregorianCalendar) .

Процесс перехода от ThreeTenABP к java.time должен быть плавным и почти безболезненным.

Когда какой фреймворк использовать

Вот диаграмма, показывающая три фреймворка и указывающая, когда использовать какую из них и в каких сценариях.

➥ Обновление: подключаемый модуль Android Gradle 4.0.0+ предлагает новую четвертую опцию, API-интерфейс, позволяющий сделать доступным подмножество функций java.time, изначально не встроенных в более ранние версии Android. См. Верхнюю часть основного ответа Каэля.


О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как java.util.Date, Calendar, и SimpleDateFormat.

Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310 .

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*занятиях. Hibernate 5 и JPA 2.2 поддерживают java.time .

Где взять классы java.time?

5 RichardKamere Aug 19 2019 at 00:02

Добавьте следующее в свой файл сборки gradle в Android Studio.

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

Создайте класс Application и инициализируйте его так:

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