Come utilizzare ThreeTenABP in Android Project

Aug 12 2016

Sto facendo questa domanda perché sono nuovo su Java e Android e ho cercato per ore cercando di capirlo. La risposta proveniva da una combinazione di risposte correlate, quindi ho pensato di documentare ciò che ho imparato per chiunque altro potesse avere difficoltà. Vedi risposta.

Sto utilizzando 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

200 kael Aug 12 2016 at 23:36

Attenzione: questa risposta, sebbene tecnicamente corretta, è ora obsoleta

Supporto per Java 8+ API desugaring ora disponibile tramite Android Gradle Plugin 4.0.0+

(Vedi anche la risposta di Basil Bourque di seguito )

Lo sviluppo della libreria ThreeTenABP è agli sgoccioli . Considera l'idea di passare al plug-in Android Gradle 4.0, java.time. * E alla sua funzione di desugaring della libreria principale nei prossimi mesi.

Per abilitare il supporto per queste API della lingua su qualsiasi versione della piattaforma Android, aggiorna il plug-in Android a 4.0.0 (o superiore) 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'
}

Risposta originale

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

Questa è una versione molto breve del PROCESSO MOLTO LUNGO per definire un nuovo standard. Tutti questi pacchetti sono più o meno la stessa cosa: librerie che forniscono funzionalità di gestione del tempo 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 le 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 (in realtà non sono sicuro che sia vero al 100%, ma è così che lo capisco). Quindi java.timeè fuori.

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

Il prossimo è ThreeTen-Backport , che trasferisce molte (ma non tutte) le java.timefunzionalità di Java 8 a Java 7. Questo va bene per la maggior parte dei casi d'uso, ma, come indicato nel readme di ThreeTenABP , ha problemi di prestazioni con Android.

Quindi l'ultima e apparentemente corretta opzione è ThreeTenABP .

Seconda scoperta: creazione di strumenti e gestione delle dipendenze

Poiché la compilazione di un programma, specialmente uno che utilizza un mucchio di librerie esterne, è complessa, Java utilizza quasi invariabilmente uno "strumento di compilazione" 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 compilazione 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, Maven Central Repository è per Maven (e Gradle) ciò che Packagist è per composer: 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 c'è leggere i documenti di Gradle qui , inclusi i loro eBook gratuiti. Se avessi letto queste settimane fa quando ho iniziato a imparare ad Android, avrei sicuramente saputo che Gradle può utilizzare 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 implicitamente 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 [project dir] /app/build.gradle

Di nuovo, ovvio per coloro che hanno esperienza nell'uso di Gradle in Java, ma mi ci è voluto un po 'per capirlo. Se vedi persone che dicono "Oh, aggiungi compile 'this-or-that.jar'" o qualcosa di simile, sappi che compileè una direttiva in quel file build.gradle che indica le 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 passato troppo tempo a capire. Se cerchi ThreeTen in Maven Central, vedrai solo i pacchetti per 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 colpito per la prima volta questo repository github, 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 fino a molto tempo dopo aver capito il resto, e finalmente ho capito che si tratta di una linea Maven Repo che punta al com.jakewharton.threetenabprepo, al contrario del org.threetenrepo. Ecco perché ho pensato che il pacchetto ThreeTenABP non fosse nel repository Maven.

Riepilogo: farlo funzionare

Ora sembra tutto abbastanza facile. Puoi ottenere funzioni di gestione del tempo moderne in un progetto Android assicurandoti che il tuo [project folder]/app/build.gradlefile abbia la implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'riga 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 Application:

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

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

java.time integrato in Android 26+

Se scegli 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 a 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 utilizzi ThreeTenABP . Successivamente, potresti eventualmente abbandonare il supporto per queste versioni precedenti di Android, per utilizzare le classi java.time in bundle con Android. Quando ciò accade, è necessario apportare poche modifiche alla base di codice oltre a (a) importistruzioni di commutazione e (b) modificare qualsiasi chiamata effettuata 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 fluido 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+ porta una nuova quarta opzione, API desugaring per rendere disponibile un sottoinsieme di funzionalità java.time non originariamente incorporate nei precedenti Android. Vedi la parte superiore della risposta principale di kael.


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ù, vedere il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .

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

Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizza 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?

5 RichardKamere Aug 19 2019 at 00:02

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

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

Crea la classe Application e inizializzala in questo modo:

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