Image for post
Image for post

Using KTX libraries

Florina Muntenescu
Dec 15, 2020 · 4 min read

When using Android Java APIs in Kotlin, you quickly realise that you’re missing out on some of the Kotlin features that make coding so much easier and pleasant. Instead of writing your own wrappers and extension functions for these APIs, take a look at the Jetpack KTX libraries. Currently, more than 20 libraries have a KTX version, creating sweet idiomatic versions of Java APIs, ranging from Android platform APIs to ViewModels, SQLite and even Play Core. In this post we’ll look at some of the APIs available and peek under the hood to see how they were made.

If you prefer watching a video to reading a blog post check it out here:


As a best practice, to ease the discoverability of ktx functionality, always import the -ktx artifact when available. As the -ktx artifact depends transitively on the non-ktx version, you don’t need to include the other artifact. For example, for viewmodel you get 2 artifacts: viewmodel and viewmodel-ktx. The -ktx artifact will contain the Kotlin extensions:

Always import the -ktx artifact

For extensions on the Android platform APIs, import the core-ktx artifact.

The majority of ktx functionality is implemented as extension functions so you’ll be able to easily find them by using auto-complete in Android Studio.

Other functionality, like the destructuring and operator overloading available on classes like Color can be discovered by checking out the list of KTX extensions.

Platform APIs — core-ktx

core-ktx provides idiomatic Kotlin functionality for APIs coming from the Android platform.

For example, if you’re working with SharedPreferences, when you want to update a value, instead of executing 3 different calls, you can just do one:

Under the hood, the ktx edit method calls the same functionality, providing a good commit default option: apply(). apply(), unlike commit(), commits the changes on disk asynchronously:

In core-ktx you’ll also find an easier way of handling frequently used platform listeners. For example, if you want to trigger an action when text was changed in an EditText, you’d have to implement all the methods of the TextWatcher, even if you’re only interested in onTextChanged(). core-ktx creates the corresponding TextWatcher methods: doOnTextChanged, doAfterTextChanged and doBeforeTextChanged, but in your Kotlin code, you just use the one you need:

This brings several benefits: your code becomes easier to read, as it’s more concise and you get better naming and nullability annotations.

You’ll find similar listener APIs for AnimatorListener and TransitionListener.

Under the hood, doOnTextChanged is implemented as an extension function on TextView — the class that also has the addTextChangedListener method. doOnTextChanged creates empty implementations for the other functions of the TextWatcher.

Jetpack APIs

The majority of extensions available are for Jetpack APIs. Here I’ll just go over some of the ones I found myself using most often.


A lot of the LiveData functionality is implemented as extension functions as well: methods like map, switchMap or distinctUntilChanged (source).

For example, using map from livedata-ktx removes the need to call { /* map function */ }, and allows us to call directly in a more Kotlin idiomatic way.

When you observe a LiveData object, you’ll have to implement an Observer. But using the observe from lifecycle-ktx, the code becomes simpler. Make sure you call import androidx.lifecycle.observe if the method isn’t found.

LiveData is ideal for exposing data to be consumed by the UI so, to convert from Flow to LiveData and from LiveData to Flow, the lifecycle-livedata-ktx artifact provides two handy extension functions: Flow.asLiveData() and LiveData.asFlow().

Activity / Fragment and ViewModel

To construct a ViewModel, you would extend the ViewModel class and implement ViewModelProvider.Factory if your ViewModel has dependencies. To instantiate it, use the viewModels delegate (read more about delegates here): by viewModels(factory):

viewModels is available in the -ktx artifact of activity and fragment.

When working with coroutines, you’ll find yourself needing to launch a coroutine in the ViewModel. The work done by the coroutine should be cancelled when the ViewModel is destroyed. Instead of implementing your own CoroutineScope, use viewModelScope. The cancellation will be done automatically for you, in ViewModel.onCleared(). Find out the ins and outs of viewModelScope from this blog post.

Room and WorkManager

Both Room and WorkManager offer coroutines support via their -ktx artifacts. As we think it’s worth covering those more in depth, stay tuned for MAD Skills articles focused on those specific libraries!

Other KTX modules

AndroidX artifacts are not the only ones to provide KTX versions:

  • Firebase has created common Kotlin extensions
  • Google Maps offers Maps and Places ktx libraries
  • Play Core has a core-ktx artifact, providing coroutines support for monitoring in-app updates

Concise, readable and Kotlin idiomatic — these are the features that will benefit your code, once you start using -ktx extensions. Stay tuned for more ways to take advantage of Kotlin and Jetpack in your app!

Android Developers

The official Android Developers publication on Medium

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store