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

193

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

Ответы:

192

Внимание: поддержка отладки API Java 8+ (Android Gradle Plugin 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.timeфункциональных возможностей Java 8 на Java 7. Это хорошо для большинства случаев использования, но, как указано в ознакомительном файле 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 для управления зависимостями в проектах Android. Кроме того, как подробно описано в этом ответе StackOverflow, начиная с Android Studio 0.8.9, Gradle неявно использует Maven Central Repository через JCenter Bintray, что означает, что вам не нужно делать никаких дополнительных настроек для настройки репозитория - вы просто перечисляете зависимостей.

Четвертое открытие: зависимости проекта перечислены в [project dir] /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'
}

Также добавьте это в класс Application:

public class App extends Application {    
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidThreeTen.init(this);
        //...
    }
}
Кель
источник
1
Спасибо за великолепный пост. Однако мне интересно, рассматривали ли вы также JodaTimeAndroid .
Боб
@Bob, я не экспериментировал с JodaTimeAndroid, но только потому, что сейчас я не работаю над чем-то, что требует этого. Из того, что я помню, java.timeреализация была хорошей (будучи в основном портом JodaTime), и я уверен, что через год или два 90% пользователей будут на Nougat +, что делает его жизнеспособным решением для разработки.
Кель
2
@Bob, JodaTime в основном такой же, как JSR-310 (даже в основном сделанный теми же парнями), за исключением того, что у JSR-310 предположительно меньше конструктивных недостатков (см. Эту статью , например). [... продолжение ниже]
М. Прохоров
2
Чтобы уточнить комментарии ... Каркас java.time ( JSR 310 ) является официальным преемником проекта Joda-Time . Оба проекта возглавляет один и тот же человек, Стивен Колебурн . Проект Joda-Time сейчас находится в режиме обслуживания, и команда рекомендует перейти на java.time.
Василий Бурк
6
Убедитесь , что вы звоните AndroidThreeTen.init(this)перед использованием API, например , в onCreate().Сме ошибки ThreeTen-портировать на Android - ZoneRulesException: время-файлы зоны данных не зарегистрированы .
Оле В.В.