Android KTX - Android development with Kotlin

In Google I/O 2018, Google introduced Android Jetpack and this has changed the way of developing a modern-day robust android application.

Jetpack is a collection of libraries, tools, and guidance to help developers write high-quality apps easier.

Jetpack was made to use the advantages of Kotlin language to make the developers more productive. So, in this blog, we will learn about the Android KTX. We will see how things have changed with the use of Android KTX.

What is Android KTX?

Android Kotlin Extensions or simply Android KTX (We will be referring it as KTX from now onwards) is a set of functionalities that allows the Kotlin developers to develop Android apps in a very sweet and pleasant way. If you are an Android developer, then you must be tired of using the old and rusty Java Android APIs. So, in order to use that Java Android APIs in Kotlin in an easier way, the developers in Android team made Android KTX.

The goal of Android KTX is not to add new features to the existing Android APIs, but to make Android development easier by using the existing API in Kotlin.

There are many features that are present in Android KTX, they are as followed :

  • Extension functions: These are the functions that helps us to extend the functionality of the class without getting into the code of that class i.e. you just have to call the function of the class.

For example, if you are inflating a view inside an adapter, then the code without using the extension function looks like:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(R.layout.view_item, parent, false)
    return ViewHolder(v)
}

So, why to use such a messy code? Just use the extension function property of Kotlin. But how to use extension function in kotlin? Let's have an example:

fun Int.triple(): Int {
    return this * 3
}

fun main(args: Array<String>) {
    var result = 10.triple()
    println(result)
}

In the above example, we have made one function triple(), which triples the value of an integer. So, in the main function, we have used the extension function calling to tripple the value passed i.e. 10 in our case. Now, let's apply this property in our previous code.

After using the extension function property, the code of LayoutInflater will be reduced to:

fun ViewGroup.inflate(layoutRes: Int): View {
    return LayoutInflater.from(context).inflate(layoutRes, this, false)
}

Very simple? Now let’s move on to the next feature

  • Extension properties: Kotlin also supports extension property. But in order to use the extension property in Kotlin, you have to explicitly provide the getter(plus setter for vars).

Without using the extension property you have to implicitly. But with the help of extension property, your code will be reduced to:

val String.isLongEnough: Boolean
    get() = this.length > 5

fun main(args: Array<String>) {
    //using extension property
    if("Kotlin".isLongEnough) {
        //rest of the code goes here
    }
}
  • Lambdas: Lambda function are anonymous functions that can be passed as arguments to methods, you can return them or you can perform all the operation that you can perform on a regular object.

In Kotlin, we define lambda function as:

{s:String -> println(s) }

Here s is an empty string which is passed as an argument to the function to print s. To assign the whole function in a variable, use the below code:

var link = {s:String -> println(s) }
  • Named parameters: This is a feature that is not present in some other object-oriented language. Kotlin provides a way to specify the name of the arguments that you are passing while a function call. For example, look at the below code of arithmeticSeriesSum() function:
fun arithmeticSeriesSum(a: Int = 1, n: Int, d: Int = 1): Int {
    return n/2 * (2*a + (n-1)*d)
}

While calling, you can specify the name of argument as:

arithmeticSeriesSum(n=10)  // Result = 55
arithmeticSeriesSum(a=3, n=10, d=2)  // Result = 120

Here n, a and d are the names of parameters.

  • Parameter default values: In Kotlin, you can pass default values to parameters of a function. For example, if a function contains two parameters and both are having some default value then if you call the function with no parameter, and then that default parameters will be used. If both parameters are passed then the new passed parameters will be used. If you pass only one parameter then, the first parameter will be assigned the value that is passed and for other variable, the default value will be used.

Following is an example of the same:

fun displaySymbol(character: Char = '=', length: Int = 15) {
    for (i in 1..length) {
        print(character)
    }
}

fun main(args: Array<String>) {
    println("Output when no argument is passed:")
    displaySymbol()

    println("Output when * is passed:")
    displaySymbol('*')

    println("Output when * and 5 are passed:")
    displayBorder('*', 5)
}

So, these are some of the features that can be used in Android KTX to make our code more readable and concise.

Now, let’s look on how Android KTX can help you in writing more precise and simpler code as never before.

  • String to Uri:

Normally in Kotlin we use Uri.parse(uriString) but Android KTX adds some extension to the String class to convert String to Uri in a very easier way.Kotlin code:

val uri = Uri.parse(myUriString)

Kotlin with Android KTX code:

val uri = myUriString.toUri()
  • SharedPreferences:

Kotlin code for editing SharedPreferences:

sharedPreferences.edit()
           .putBoolean(key, value)
           .apply()

Android KTX code:

sharedPreferences.edit { 
    putBoolean(key, value) 
}
  • Displaying a Toast message:

Android KTX makes the way of displaying a toast message very easier and simpler.Kotlin code:

Toast.makeText(context, R.string.toast_message, Toast.LENGTH_SHORT).show()

Android KTX code:

toast(R.string.toast_message)
  • Fragment Transactions:

With the help of Android KTX, the code for transaction of fragments gets reduced.Kotlin code for Fragment Transactions:

supportFragmentManager
    .beginTransaction()
    .replace(R.id.container, customFragment, CustomFragment.TAG)
    .commitAllowingStateLoss()

Android KTX code for Fragment Transation:

supportFragmentManager.transaction(allowStateLoss = true) {
            replace(R.id.container, customFragment, CustomFragment.TAG)
}

So, these are some of the examples where you can use the Android KTX to make your code more readable and the number of lines you write in your code will also be reduced. No more lines of code by using Android KTX.

Use Android KTX in your Android Project

In order to use Android KTX in your project, you have to add some dependencies in your project.

Add the following dependency to your project’s build.gradle file:

dependencies {
    implementation 'androidx.core:core-ktx:1.0.1'
}

Since Android KTX is divided into various modules(we will learn about the modules in the section below of this blog). So, to use a particular module, add dependencies to your app’s build.gradle file. For example, if you want to add the fragment-ktx module, then add the below dependency:

dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.0.1'
}

Android KTX Modules

The whole Android KTX is divided into a number of modules that allows you to use the KTX features in your application and by doing so you will import only those features that you need. Some of the basic modules that we use on a regular basis are:

  • Core KTX
  • Fragment KTX
  • Palette KTX
  • SQLite KTX
  • Collections KTX

Lets look about these modules in more detail.

Core KTX

Core KTX contains all the libraries that are present in the Android Framework. The packages that are present in the Core KTX module are:

  • androidx.core.animation
  • androidx.core.content
  • androidx.core.graphics
  • androidx.core.graphics.drawable
  • androidx.core.net
  • androidx.core.os
  • androidx.core.preference
  • androidx.core.text
  • androidx.core.transition
  • androidx.core.util
  • androidx.core.view
  • androidx.core.widget

Fragment KTX

Fragment KTX is used to simplify the fragment API. For example, if you want to do the fragment transactions using the Fragment KTX, then the code will be:

fragmentManager().commit {
   addToBackStack("...")
   setCustomAnimations(
           R.anim.enter_anim,
           R.anim.exit_anim)
   add(fragment, "...")
}

Palette KTX

This is used to simplify the use of colors in Android by taking advantage to advance feature of Kotlin. For example, you can retrieve the selected swatch for a given palette by using the below code:

val palette = Palette.from(bitmap).generate()
val swatch = palette[target]

SQLite KTX

This is very useful as all the SQL related code are included in the transaction as follows:

db.transaction {
    // insert data
}

Collection KTX

If you are working on an Android app that requires a lot of memory related operation, then you must be using ArrayMap, LongParseArray, LruCache and many more. But to work with these memory-efficient collections efficiently, you can use Collection KTX in your app. For example:

// Combine 2 ArraySets into 1.
val combinedArraySet = arraySetOf(1, 2, 3) + arraySetOf(4, 5, 6)

// Combine with numbers to create a new sets.
val newArraySet = combinedArraySet + 7 + 8

ViewModel KTX

If you want to work with coroutines from your ViewModel, then you can make use of ViewModel KTX that provides a viewModelScope() and with the help of this function you can easily call coroutines from the your ViewModel. So, instead of creating a new scope for each ViewModel just use viewModelScope(). Following is an example of viewModelScope() that makes a network request in background.

class MainViewModel : ViewModel() {
    // Make a network request without blocking the UI thread
    private fun makeNetworkRequest() {
        // launch a coroutine in viewModelScope
        viewModelScope.launch  {
            remoteApi.slowFetch()
            ...
        }
    }

    // No need to override onCleared()
}

WorkManager KTX

Work manager is used to run some background task even if the app will be closed. Background app can be started when the app is in background or foreground.

WorkManager KTX adds function like Operations and ListenableFeatures to add support for Kotlin coroutines. To suspend the current coroutine, you can use:

// Inside of a coroutine...

// Run async operation and suspend until completed.
WorkManager.getInstance()
        .beginWith(longWorkRequest)
        .enqueue().await()

// Resume after work completes...

Wrap Up

We have seen that the Android KTX is a very nice part of the Android JetPack. It doesn’t provide any new features and functionalities, rather it enhances the way of using the existing APIs using the Kotlin language. We saw some cool features of Android KTX and later on, we saw how to implement various modules of Android KTX in our project.

So, that’s all for this blog.

Happy Kotlin-ing :)

Team MindOrks.