Как использовать ThreeTenABP в Android Project
Я задаю этот вопрос, потому что я новичок в 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)
Ответы
Внимание: этот ответ, хотя и верный с технической точки зрения, теперь устарел.
Поддержка удаления сахара из 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);
//...
}
}
Принятый ответ Каэля верен. Кроме того, я упомяну пару вещей и представлю схему получения функциональности 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?
- Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 и более поздние версии - часть стандартного Java API с объединенной реализацией.
- В Java 9 добавлены некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
- Android
- Более поздние версии Android связывают реализации классов java.time .
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP… .
Добавьте следующее в свой файл сборки gradle в Android Studio.
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
Создайте класс Application и инициализируйте его так:
class App : Application() {
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
}
}