26 January 2021
Use the Java 8 Time API in an Android application

Java 8’s Time API significantly reduced the complexity of working with dates and times (Just look at the amount of code you need to write to accomplish a lot of common tasks using the old Date class).

However, the Android SDK only added these classes in version 26 (Android 8.0 Oreo). Trying to run an application that uses these classes on an older device will throw a java.lang.NoClassDefFoundError exception which is caused by a java.lang.ClassNotFoundException exception.

It’s worth remembering that you might not be directly using these classes yourself, you may be using a library that’s expecting them to be present (perhaps one that wasn’t designed explicitly for Android).

There have been several workarounds over the years to replace these classes, however now it’s as simple as switching on syntax desugaring.

Let’s take a look at some example code:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    val now = LocalDateTime.now()
    Log.d("MainActivity", now.toString())

}

This code simply creates a LocalDateTime object using the current date and time and then prints a log message with the toString() method. Running the application on an ancient Moto G4 will predictably throw a java.lang.NoClassDefFoundError exception as soon as it reaches LocalDateTime.now().

Enabling Syntax Desugaring

Head over to your module-level build.gradle file (not the one that’s in the root directory- the one that’s typically in the app directory). Ensure your compileOptions block looks like this:

android {

    ...

    compileOptions {

        coreLibraryDesugaringEnabled true

        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8

    }

}

Running the application now will cause Gradle to tell you:

coreLibraryDesugaring configuration contains no dependencies. If you intend to enable core library desugaring, please add dependencies to coreLibraryDesugaring configuration.

You simply need to add the coreLibraryDesugaring dependency to the dependencies section of the same file.

dependencies {

    ...

    coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1"

}

Now if you run the application on the same device, no NoClassDefFoundError is thrown, and the log message is printed successfully.