Come usare ThreeTenABP nel progetto Android


193

Sto facendo questa domanda perché sono nuovo su Java e Android e ho cercato per ore cercando di capirlo. La risposta è nata da una combinazione di risposte correlate, quindi ho pensato che avrei documentato ciò che ho appreso per chiunque abbia difficoltà. Vedi la risposta

Sto usando Android Studio 2.1.2 e la mia configurazione Java è la seguente:

>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)

Risposte:


192

Attenzione: supporto per la desugarazione dell'API Java 8+ (Android Gradle Plugin 4.0.0+)

Lo sviluppo di questa libreria ( ThreeTenABP ) è agli sgoccioli . Considera di passare al plug-in Android Gradle 4.0, java.time. * E alla sua funzione di desugarazione della libreria principale nei prossimi mesi.

Per abilitare il supporto per queste API di lingua su qualsiasi versione della piattaforma Android, aggiorna il plug-in Android alla 4.0.0 (o successiva) e includi quanto segue nel file build.gradle del tuo modulo:

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'
}

Prima scoperta: perché devi usare ThreeTenABP invece di java.time , ThreeTen-Backport o persino Joda-Time

Questa è una versione davvero breve del PROCESSO MOLTO LUNGO per definire un nuovo standard. Tutti questi pacchetti sono praticamente la stessa cosa: librerie che forniscono funzionalità di gestione dei tempi buone e moderne per Java. Le differenze sono sottili ma importanti.

La soluzione più ovvia sarebbe quella di utilizzare il java.timepacchetto integrato , poiché questo è il nuovo modo standard per gestire l'ora e le date in Java. È un'implementazione di JSR 310 , che era una nuova proposta standard per la gestione del tempo basata sulla libreria Joda-Time .

Tuttavia, è java.timestato introdotto in Java 8 . Android fino a Marshmallow funziona su Java 7 ("Android N" è la prima versione a introdurre funzionalità del linguaggio Java 8). Pertanto, a meno che tu non stia prendendo di mira solo Android N Nougat e versioni successive, non puoi fare affidamento sulle funzionalità del linguaggio Java 8 (non sono sicuro che questo sia vero al 100%, ma è così che lo capisco). Quindi java.timeè fuori.

L'opzione successiva potrebbe essere Joda-Time , poiché JSR 310 era basato su Joda-Time. Tuttavia, come indica il readme di ThreeTenABP , per una serie di motivi, Joda-Time non è l'opzione migliore.

Il prossimo è ThreeTen-Backport , che esegue il back-port di gran parte (ma non tutte) della java.timefunzionalità Java 8 su Java 7. Questo va bene per la maggior parte dei casi d'uso, ma, come indicato nel readme ThreeTenABP , ha problemi di prestazioni con Android.

Quindi l'ultima e apparentemente corretta opzione è ThreeTenABP .

Seconda scoperta: strumenti di costruzione e gestione delle dipendenze

Poiché la compilazione di un programma - in particolare uno che utilizza un gruppo di librerie esterne - è complessa, Java utilizza quasi sempre uno "strumento di costruzione" per gestire il processo. Make , Apache Ant , Apache Maven e Gradle sono tutti strumenti di compilazione utilizzati con i programmi Java (vedere questo post per i confronti). Come notato più avanti, Gradle è lo strumento di creazione scelto per i progetti Android.

Questi strumenti di compilazione includono la gestione delle dipendenze. Apache Maven sembra essere il primo a includere un repository di pacchetti centralizzato. Maven ha introdotto il Maven Central Repository , che consente funzionalità equivalenti a php composercon Packagist e Ruby gemcon rubygems.org. In altre parole, il Maven Central Repository è per Maven (e Gradle) ciò che Packagist è per compositore - una fonte definitiva e sicura per i pacchetti con versione.

Terza scoperta: Gradle gestisce le dipendenze nei progetti Android

In cima alla mia lista di cose da fare è leggere i documenti Gradle qui , compresi i loro eBook gratuiti. Se avessi letto queste settimane fa quando ho iniziato ad imparare Android, avrei sicuramente saputo che Gradle può usare il Maven Central Repository per gestire le dipendenze nei progetti Android. Inoltre, come dettagliato in questa risposta StackOverflow, a partire da Android Studio 0.8.9, Gradle utilizza Maven Central Repository in modo implicito tramite JCenter di Bintray, il che significa che non è necessario eseguire alcuna configurazione aggiuntiva per impostare il repository: è sufficiente elencare il dipendenze.

Quarta scoperta: le dipendenze del progetto sono elencate in [dir progetto] /app/build.gradle

Ancora una volta, ovvio per coloro che hanno qualche esperienza con Gradle in Java, ma mi ci è voluto un po 'di tempo per capirlo. Se vedi persone che dicono "Oh, basta aggiungere compile 'this-or-that.jar'" o qualcosa di simile, sappi che compileè una direttiva in quel file build.gradle che indica dipendenze in fase di compilazione. Ecco la pagina ufficiale di Gradle sulla gestione delle dipendenze.

Quinta scoperta: ThreeTenABP è gestito da Jake Wharton, non da ThreeTen

Ancora un altro problema che ho trascorso troppo tempo a capire. Se cerchi ThreeTen in Maven Central, vedrai solo i pacchetti threetenbp, no threetenabp. Se vai al repository github per ThreeTenABP , vedrai quella famigerata compile 'this-or-that'riga nella sezione Download del file Leggimi.

Quando ho raggiunto questo repository github per la prima volta, non sapevo cosa significasse quella riga di compilazione e ho provato a eseguirlo nel mio terminale (con un errore ovvio e prevedibile). Frustrato, non ci sono tornato molto tempo dopo aver capito il resto, e finalmente ho capito che si tratta di una linea Maven Repo che punta al com.jakewharton.threetenabprepository, al contrario del org.threetenrepository. Ecco perché pensavo che il pacchetto ThreeTenABP non fosse nel repository Maven.

Riepilogo: farlo funzionare

Ora sembra tutto abbastanza semplice. Puoi ottenere le moderne funzioni di gestione del tempo in un progetto Android assicurandoti che il tuo [project folder]/app/build.gradlefile abbia la implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'linea nella sua dependenciessezione:

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'
}

Aggiungilo anche alla classe Applicazione:

public class App extends Application {    
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidThreeTen.init(this);
        //...
    }
}

1
Grazie per il grande post. Tuttavia, mi chiedo se hai preso in considerazione anche JodaTimeAndroid .
Bob,

@Bob, non ho sperimentato JodaTimeAndroid, ma solo perché non sto davvero lavorando su nulla in questo momento che lo richiede. Da quello che ricordo, l' java.timeimplementazione andava bene (essendo sostanzialmente un porto di JodaTime), e sono sicuro che tra un altro anno o due, il 90% degli utenti sarà su Nougat +, rendendolo una soluzione praticabile per lo sviluppo.
Kael,

2
@Bob, JodaTime è sostanzialmente lo stesso di JSR-310 (anche fondamentalmente realizzato dagli stessi ragazzi), tranne per il fatto che JSR-310 presumibilmente ha meno difetti di progettazione (vedi questo articolo , ad esempio). [... continua sotto]
M. Prokhorov,

2
Per chiarire i commenti ... Il framework java.time ( JSR 310 ) è il successore ufficiale del progetto Joda-Time . Entrambi i progetti sono guidati dallo stesso uomo, Stephen Colebourne . Il progetto Joda-Time è ora in modalità manutenzione, con il team che consiglia la migrazione a java.time.
Basil Bourque,

6
Assicuratevi di chiamare AndroidThreeTen.init(this)prima di utilizzare l'API, ad esempio in onCreate().Vedere errore ThreeTen-Backport su Android - ZoneRulesException: i file di dati di fuso orario Nessuno .
Ole VV,

5

La risposta accettata da Kael è corretta. Inoltre, citerò un paio di cose e fornirò un diagramma su come ottenere la funzionalità java.time .

java.time integrato in Android 26+

Se hai come target Android 26 o versioni successive, troverai un'implementazione di JSR 310 ( classi java.time ) in bundle con Android. Non è necessario aggiungere ThreeTenABP .

API quasi identiche

Giusto per chiarire, ThreeTenABP per Android è un adattamento della libreria ThreeTen-Backport che porta la maggior parte delle funzionalità java.time su Java 6 e Java 7 . Questo back-port condivide quasi un'API identica con java.time .

Supponiamo che ora stai prendendo di mira Android prima del 26, quindi usi ThreeTenABP . Successivamente, potresti eventualmente eliminare il supporto per queste versioni precedenti di Android, per utilizzare le classi java.time in bundle con Android. Quando ciò accade, è necessario apportare alcune modifiche alla base di codici diversi da (a) importistruzioni di commutazione e (b) modificare le chiamate effettuate org.threeten.bp.DateTimeUtilsper utilizzare i nuovi metodi di conversione aggiunti alle vecchie classi data-ora legacy ( Date, GregorianCalendar) .

Il processo di transizione da ThreeTenABP a java.time dovrebbe essere regolare e quasi indolore.

Quando utilizzare quale framework

Ecco un grafico che mostra i tre framework e indica quando utilizzare quale in quali scenari.

➥ Aggiornamento: Android Gradle Plugin 4.0.0+ offre una nuova quarta opzione, l' API desugaring per rendere disponibile un sottoinsieme di funzionalità java.time non originariamente incorporato in Android precedente. Vedi la parte superiore della risposta principale di Kael.

Tabella di quale libreria java.time utilizzare con quale versione di Java o Android


Informazioni su java.time

Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date, Calendar, e SimpleDateFormat.

Per saperne di più, consulta il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

Il progetto Joda-Time , ora in modalità manutenzione , consiglia la migrazione alle classi java.time .

Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizzare un driver JDBC conforme a JDBC 4.2 o successivo. Non c'è bisogno di stringhe, non c'è bisogno di java.sql.*classi. Hibernate 5 e JPA 2.2 supportano java.time .

Dove ottenere le classi java.time?


4

Aggiungi quanto segue nel tuo file gradle di build in Android Studio.

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

Creare la classe Application e inizializzarla in questo modo:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.