Як використовувати 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

Увага: підтримка знедолення Java 8+ API (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 і вище, ви не можете покладатися на функції мови 8 Java (я фактично не впевнений, що це 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's gemз rubygems.org. Іншими словами, центральний сховище Maven - це Maven (та Gradle), що складається Packagist - композитор - остаточне та безпечне джерело для пакунків із версією.

Третє відкриття: Gradle обробляє залежності в Android-проектах

У моєму списку справ - читати тут документи Gradle , включаючи їх безкоштовні електронні книги. Якби я читав ці тижні тому, коли я почав вивчати Android, я б точно знав, що Gradle може використовувати Maven Central Repository для управління залежностями в Android-проектах. Крім того, як детально описано у цій відповіді StackOverflow, що стосується Android Studio 0.8.9, Gradle використовує Maven Central Repository неявно через JCenter Bintray, а це означає, що вам не потрібно робити додаткових конфігурацій для налаштування репо - просто ви перелічите список залежності.

Четверте відкриття: залежність проекту перерахована в [проект 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 repo, я не знав, що означає цей рядок компіляції, і спробував запустити його в своєму терміналі (з очевидним і передбачуваним збоєм). Розчарований, я не повернувся до нього, поки довго не зрозумів решту, і нарешті зрозумів, що це лінія 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
Для уточнення коментарів… Ява.time рамок ( JSR 310 ) є офіційним продовжувачем проекту Joda-Time . Обидва проекти веде той самий чоловік, Стівен Колбурн . Проект Joda-Time зараз перебуває в режимі обслуговування, команда радить перейти на java.time.
Василь Бурк

6
Переконайтеся , що ви дзвоните AndroidThreeTen.init(this)перед використанням API, наприклад , в onCreate().Сме помилки ThreeTen-перенести на Android - ZoneRulesException: час-файли зони даних не зареєстровані .
Оле ВВ

5

Прийнята відповідь kael є правильною. Крім того, я згадаю пару речей і надам схему отримання функцій 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 Plugin 4.0.0+ пропонує новий 4-й варіант, API знешкодження для надання доступного підмножини функцій java.time, спочатку не вбудованих у попередній Android. Дивіться верхню частину основної відповіді від kael.

Таблиця, яку бібліотеку java.time використовувати з якою версією Java чи Android


Про java.time

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

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

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

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

Де отримати класи java.time?


4

Додайте наступне у свій файл gradile gradle в Android Studio.

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

Створіть клас програми та ініціалізуйте його так:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.