Category: Teaching

Android KTX – Android development with Kotlin

Android KTX – Android development with Kotlin

Introduction

Android KTX is an open source library or set of functionalities designed to make the Android development with Kotlin even more pleasant. You can find its website here. The abbreviation KTX stands for Kotlin Extensions, so this library is basically a set of extension functions, extension properties and other top-level functions. In this article, we take a look at what’s inside this library and how we can take advantage of it. This library’s goal is not to add new features to the existing Android APIs, but rather make those APIs easier to use by leveraging the features of the Kotlin language.

Structure of Android KTX

A very important thing to note at the beginning is that Android KTX provides functionalities which would be added to many individual projects by the developers most of the time anyway. Arguably, there are also many things that will get included by adding the dependency, which are not going to be used. Thanks to the ProGuard, all the unused code will get stripped out, so there should be no worry regarding the library footprint. Now, let’s take a look at some of the very important and crucial concepts of the Kotlin language which are used for building the Android KTX.

Extension functions

An extension function is one of the Kotlin features that allows us to add a functionality to an existing class without modifying it directly. By adding extension functions to a class, they are represented as simple static methods on bytecode level. Then, we can call those functions on the objects of that class type, just as they were part of the class’s API initially. Here is an example to give a little better insight into the way it’s done. Say, we want to add an extension function to the String class to print itself. Here is how we can do it:

fun String.printSelf() {
    println(this)
}

Inside the extension function, we can use this to refer to the current object on which the function is being executed. Then, this function becomes available to be called on any object of String type. So we can do:

fun usage() {
    "Kotlin Rocks".printSelf()
}

Extension properties

Similarly to extension function, Kotlin supports extension properties. Also, the way we define them is quite the same:

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

Then, we can use this extension property on any object of String type:

"Kotlin".isLongEnough

The behavior of the extension property can only be defined by explicitly providing getter (plus setter for vars). Initializing those properties the ordinary way doesn’t work. The reason behind this is that an extension property does not insert members into the type, so there is no efficient way for it to have a backing field.

Top level functions

In Kotlin, a function is a first-class citizen. We are allowed to define functions in Kotlin files (.kt) which could afterward be accessed and used from other Kotlin files. This is a very powerful concept. If we define a file inside a package com.example and define functions in it, they can be used simply by importing them into the usage side. Here is an example:

package com.example

fun sum(x: Int, y: Int): Int = x + y

now this function can be accessed and used from any other Kotlin file by simply importing it like this:

import com.example.sum

fun test() {
    println(sum(1, 2))
}

An important note here is the access modifier. In the example above, the function sum does not have defined an access modifier, and in Kotlin it’s public by default. Being public, it makes the sum function accessible from any other Kotlin file. Kotlin also has an internal access modifier keyword, which would make this function accessible only in the module where this file exists (a module could contain many different packages). Ultimately, the function could also be private which will make it accessible only from inside the file where it is defined.

Default arguments

Most probably, you are familiar with the overloading concept like in Java already. Overloading is a concept that allows us to define constructors or methods with the same signature, only differing in their parameter list (both types and number of parameters could be different). In Kotlin, this concept is taken a step further, so we could achieve the same result by defining a single function, by specifying default values to some or all of the arguments. Eventually, it boils down to the approach used in Java again. Let’s take a look at the following example:

fun greet(firstName: String, lastName: String = "") {
    println("Hello $firstName $lastName")
}

In this example, the function takes two arguments, but the lastName is optional because by default its value is going to be an empty String. So, when calling this function we are only required to supply a firstName, and we can call it this way:

greet("John")

Kotlin also supports named arguments, so we could call a function supplying the arguments by their names:

greet("John", lastName = "Doe")

This is particularly useful when we have a function with multiple optional arguments and we want to call it with supplying only specific ones, or in a different order.

You can read more about Kotlin’s awesome features in this article.

Deep Dive into Android KTX

Now, as we know what the Android KTX library is based on, let’s dig and observe some of the most common extension functions.

Converting URL to URI

To begin with, there is a very simple extension function on the Uri class. Many times in Android, we need to convert a String URL into a Uri object, for instance when creating an Intent with data etc. The way we are usually doing this is by calling Uri.parse("string_url"). Android KTX defines an extension function that does the job. Here is how it looks like:

inline fun String.toUri(): Uri = Uri.parse(this)

so we can use it by calling toUri() on any string, like this:

"any_sting_url".toUri()

Editing shared preferences

Next, let’s take a look at an extension function defined on the SharedPreferences interface. The usual way of putting values into the SharedPreferences in Android is to call edit() in order to obtain the SharedPreferences.Editor instance. Then, we can insert the values by calling editor.putType("key", typeValue). After that, it is very important to call apply() or commit() on the editor, in order for the values to be stored in the SharedPreferences. Many times we forget doing so, and we waste some time debugging until we notice what is happening. A usual example of storing values in the SharedPreferences looks like this:

val editor = sharedPreferences.edit()
editor.putString("key", value)
editor.apply()

By using the Android KTX extension on the SharedPreferences the code shortens and simplifies quite a lot, and it becomes:

sharedPreferences.edit {
    putString("key", value)
}

The relevant extension function looks like this:

inline fun SharedPreferences.edit(
    commit: Boolean = false,
    action: SharedPreferences.Editor.() -> Unit
) {
    val editor = edit()
    action(editor)
    if (commit) {
        editor.commit()
    } else {
        editor.apply()
    }
}

The first parameter to this function is a Boolean value that controls the call to the editor, whether it would use the commit() or the apply() call. Clearly, by default this value is set to false which means by default the function will call apply() on the editor. A more interesting parameter is the second one. It’s a function literal with a receiver, and the receiver is of type SharedPreferences.Editor. It means that when calling this function, we can use lambda over the receiver, so we can directly call functions that are exposed by the receiver type without additional qualifiers. This is shown with the putString call.

Operating on view before drawing

Most of the apps we are using every day are having some sort of lists where some images are being loaded. Often, those images are of a different size, and the image sizes are usually provided in the response. Since the images are normally loaded in the background, we want to allocate the space required for the image to be displayed, and once it’s loaded we already have the space allocated, so we would avoid UI expanding when the image is being displayed, which prevents the UI flickering effect. This is usually done by using a ViewTreeObserver which provides an OnPreDrawListener. This listener has a callback that is being called before the view drawing. For our images example, usually we set the view sizes that are provided in the response inside this callback, and we apply some default background (for example gray). That is one of the many use cases of the ViewTreeObserver observer and its OnPreDrawListener. Here is a snippet that shows the way we normally approach it:

view.viewTreeObserver.addOnPreDrawListener(
    object : ViewTreeObserver.OnPreDrawListener {
        override fun onPreDraw(): Boolean {
            viewTreeObserver.removeOnPreDrawListener(this)
            performSomethingOverTheView()
            return true
        }
    })

Android KTX has defined an extension function on the View type named doOnPreDraw() that simplifies the above snippet, so it would become:

view.doOnPreDraw {
     performSomethingOverTheView()
}

There are also some other nice extensions defined on the View type which are working with the view visibility, updating view padding or layout params etc.

Working with bundle

Bundles are a very common thing in Android, but working with bundles is often quite a boilerplate. The way we normally compose a bundle looks like this:

val bundle = Bundle()
bundle.putString("key", "value")
bundle.putString("keyBoolean", true)
bundle.putString("keyInt", 1)

Android KTX defines a top-level function named bundleOf(), and by using it, composing bundle becomes a lot nicer:

val bundle = bundleOf("key" to "value", "keyBoolean" to true, "keyInt" to 1)

There is also a persistableBundleOf() function for creating a PersistableBundle but it’s available for API version 21 and up. Similarly, there is a contentValuesOf() function that could be used in the same way as the functions for creating bundle above, and it returns a ContentValues object.

Iteration over view group

Working with ViewGroup in Android is quite a common thing. The ViewGroup is a kind of container that could contain other views called children. Many times we need to loop through its children, but the traditional way to do so could be quite a mess. Android KTX has defined an extension property that exposes its children, and here is how it looks like:

val ViewGroup.children: Sequence<View>
    get() = object : Sequence<View> {
        override fun iterator() = this@children.iterator()
    }

As we can see, the children property is returning a sequence of child views, and it allows us to write very concise loops over any ViewGroup type:

viewGroup.children.forEach {
    doSomething(it)
}

Displaying toast

One of the most common ways of displaying some sort of short info to the user is a Toast. When displaying a toast by using the standard API, we have to pass the Context, the actual message that we want to be displayed, whether it is a String or a resource reference to load value from the strings.xml, and the toast duration. Since we cannot display a toast without having a Context, and since most of the time the toast duration is its Toast.LENGTH_SHORT constant, it would be great to have an option to display a toast by simply calling a function and passing the actual message argument. A common way to achieve this is by defining some sort of base class that defines such method, and then it would be called from the subclasses. However, Android KTX defines an extension functions to the Context type for displaying toasts. It takes 2 arguments, the message and the duration, while the duration is being set to Toast.LENGTH_SHORT by default. So we can call to display toast wherever we have a Context by simply passing the message argument, whether it is a String type or a reference to the string resources:

toast("Hello")
toast(R.string.hello)

Wrap Up

Android KTX is a very nice part of the Android JetPack project, and as we’ve seen it contains quite some nice ways to improve the Android development we are used to. As told before, it doesn’t provide any new functionalities, but rather simplifies the APIs which are already provided by the Android SDK. Here is a nice talk from the Google I/O 2018 by Jake Wharton, where he elaborates more on the Android KTX. This article only scratches the surface, and there are many more fun things to be revealed inside the Android KTX, related to animation, database, location, graphics, text and so on. Also, the team is welcoming new contributions, which is great, so if you have an idea that is not there yet, feel free to submit it.

Jovche is an Android developer based in The Netherlands, working on Android for the last 8 years. He has a big passion for clean code, TDD, getting things done, professional behavior, and software craftsmanship.

Please follow and like this Blog 🙂
Kotlin Nullability Features

Kotlin Nullability Features

Null-Safe Programming – The Kotlin Way

Disclaimer: This ktor article was originally published in the Dzone Java Guide 2018, which can be downloaded here.

In this article, we will review the problems that may be caused by null pointers and how to avoid them in Java. After that, the article demonstrates how Kotlin nullability features work and how they improve your code.

As Java developers, we’re very accustomed to NullPointerExceptions (NPE) that are thrown at the runtime of an application. This almost always happens unintentionally in consequence of a bug, which is based on unrecognized references to null. The null reference is often used to indicate absent values, which isn’t obvious to the programmer in many cases. Although Java relies on strong static typing, it doesn’t let you distinguish between reference types that can and cannot hold a null reference. Have a look at the following code example:

Device audio = new DeviceProvider().getAudioDevice();
String audioName = audio.getName();

The method getAudioDevice returns an object of type Device but might return null in order to denote the absence of that device on particular systems. Well documented methods will describe exactly that behavior, which still requires the developer to be very attentive. Not knowing about the possibility of a returned null reference is going to cause an awful NullPointerException in the subsequent call to getName. Wouldn’t it actually be nice if we were able to identify the method’s returned Device type as nullable (or non-nullable respectively) firsthand?

Null-Safety in Java

We have to find strategies that help us avoiding unwanted bugs due to NPEs. A common approach is to defensively check for null references and handle these cases in a way that makes more sense, such as providing default values or throwing more meaningful exceptions. Applying this to the previous example brings us to the following solution:

Device audio = new DeviceProvider().getAudioDevice();
String audioName;
if (audio != null) {
    audioName = audio.getName();
} else {
    throw new IllegalStateException("This system does not provide an audio device.");
}

Constructs like these are part of any Java project and the approach works well unless you forget to add checks for certain variables. It’s a fairly error-prone approach and doesn’t mitigate the fact that using null as a representative for absent things is risky.

Does Java offer any more sophisticated solutions to this problem? It does, at least in some situations. The Java SE 8 introduced the Optional type that acts as a “container object which may or may not contain a non-null value”. This sounds very promising and needs to be considered next.

Java SE 8 Optional

The Optional type is a container that wraps another object, which can theoretically be null. Code that works on instances of Optional needs to handle the possible nullability in a rather explicit way:

Optional audio = new DeviceProvider().getAudioDevice();
String audioName = audio
    .flatMap(Device::getName)
    .orElseThrow(() -> new IllegalStateException("This system does not provide an audio device."));

The getAudioDevice method was adjusted to return an Optional, which doubtlessly indicates to the client that the device can be absent. Instead of carelessly accessing that nullable type, the Optional type can be used for handling the possible nullability in various ways. These include providing default values and throwing exceptions with the help of simple methods like orElse and orElseThrow respectively. Furthermore, it literally forces the client to think about the potential null case.

Unfortunately, the whole Optional story already ends with this use case very suddenly. As stated by Java language architect Brian Goetz in this StackOverflow post, the Optional type was not intended as a “general purpose Maybe […] type” but a way to let libraries and APIs express the absence of a return type (as we saw in the previous example).

For further usage examples of Optional, you should find a suitable article in your preferred search engine.

After all, the Optional type is a great way to provide more explicit APIs that let the corresponding callers know exactly when null handling is required just by observing the method’s signature. Nevertheless, it’s not a holistic solution since it isn’t meant to replace each and every null reference in the source code. Aside from that, can you safely rely on method return types, which are not marked as Optional?

Kotlin Nullability: Null-Safety in Kotlin

After we have seen the rather unsafe null handling in the Java language, this section will introduce an alternative approach: The Kotlin programming language, as an example, provides very sophisticated means for avoiding NullPointerExceptions.

The language’s type system differentiates between nullable and non-nullable types and every class can be used in both versions. By default, a reference of type String cannot hold null, whereas String? allows it. This distinction on its own doesn’t make a very big difference obviously. Therefore, whenever you choose to work with nullable types, the compiler forces you to handle possible issues, i.e. potential NPEs, appropriately.

//declare a variable with nullable String type, it's OK to assign `null` to it
var b: String? = "possiblyNull"

// 1. does not compile, could throw NPE
val len = b.length

// 2. Check nullability before access
if (b != null){
    b.length
}

// 3. Use safe operator
val len = b?.length

This code example shows different ways of working with nullable types (String? in this case). As demonstrated first, it’s not possible to access members of nullable types directly since this would lead to the same problems as in Java. Instead, traditionally checking whether that type is not null makes a difference. This action persuades the compiler to accept invocations on the variable (inside the if-block) as if it were not nullable. Note that this does not work with mutable vars because they could possibly be set to null from another thread between the check and first action in the block.
As an alternative to explicit checks, the safe call operator ?. can be used. The expression b?.length can be translated to “call length on b if b is not null, otherwise return null“. The return type of this expression is of type Int? because it may result in null. Chaining such calls is possible and very useful because it lets you safely omit a great number of explicit checks and makes the code much more readable:

person?.address?.city ?: throw IllegalStateException("No city associated to person.")

Another very useful operator is the elvis operator ?: that perfectly complements the safe call operator for handling else cases. If the left-hand expression is not null, the elvis operator returns it, otherwise, the right-hand expression will be called.

The last operator that you need to know is called not-null assertion operator !!. It converts any reference to a non-null type. This unchecked conversion may cause an NPE if that reference is null after all. The not-null assertion operator should only be used with care:

person!!.address!!.city //NPE will be thrown if person or address is null

In addition to the shown operators, the Kotlin library provides plenty of helpful functions like String?::IsNullOrEmpty(), String::toDoubleOrNull() and List::filterNotNull(), to name just a few. All of them support the developer in proper nullability handling and make NPEs almost impossible.

Interop between both languages

One of the key attributes of Kotlin is its fantastic interoperability with Java source code. You can easily mix both languages in a project and call Kotlin from Java and vice versa. How does that work in the case of null safety, though?

As learned earlier in this article, every Java reference can be null, which makes it hard for Kotlin to apply its safety principles to them meaningfully. A type coming from Java is called platform type, denoted with an exclamation mark, e.g. String!. For these platform types, the compiler isn’t able to determine whether it’s nullable or not due to missing information. As a developer, when a platform type is e.g. assigned to a variable, the correct type can be set explicitly. If you assign a platform type String! to a variable of the non-nullable type String, the compiler allows it and, as a consequence, safe access to that variable isn’t being enforced. Nevertheless, if that decision turns out to be wrong, i.e. a null reference is returned, NPEs will be thrown at runtime. Fortunately, there’s a solution that allows providing more information to the Kotlin compiler by applying certain annotations to the corresponding Java methods. This enables the compiler to determine actual nullability information and makes platform types unneeded.

Bottom Line

It’s important to understand that Kotlin does not try to avoid null references as such but raises the attention for null-related issues and especially NPEs enormously. If you take care of platform types and defensively decide to use them as nullable ones or apply the mentioned annotations to your Java libraries, you should be safe. NullPointerExceptions will be a thing of the past. As set out above, the Kotlin language provides many useful operators and other functions that simplify working with nullable types tremendously by making use of its clever type system. We can hope to see similar solutions in future Java versions soon.

Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂
Why you should start contributing to StackOverflow

Why you should start contributing to StackOverflow

A little History

A few years back, when I started getting into programming, I googled a lot of the problems I was facing during the day and mostly found my answers on StackOverflow. The place that every programmer is kind of dependent on. I still face problems and I still find my answers on StackOverflow. Something has changed, though. I don’t only consume content on the website but also contribute to it. Until May 2017, I didn’t even have an account on StackOverflow. At this time, I was getting interested in knowing how it’s like to answer questions instead of just reading them. I enjoyed helping others to solve their Kotlin-related problems ever since I started learning the Kotlin programming language. This was my initial motivation for creating an account and contributing to StackOverflow.

The Kotlin Gold Badge

A few weeks back, after 10 months of answering about 400 questions, I was awarded the golden Kotlin badge, which means that I spend quite some time on the platform already. I was always motivated to receive the badge since only three other people got it by then. You can become kind of addicted to answering actually… 😉

stackoverflow-kotlin-gold-s1m0nw1

Lessons Learned

Teaching improves yourself

When I began with contributing to StackOverflow, I had to realize that it can be quite hard to give answers on the fly. It’s not that easy. You most often need to think about the way of looking at the problem from the questioner’s point of view. Regularly, you’ll find yourself researching for answers by studying the documentation, forums and other resources. Most questions also require you to solve the presented problem in your own IDE before coming up with a solution. It can be really time-consuming if you really try to understand other people’s problems. Nevertheless, the whole effort was totally worth it since I learned so many things about the Kotlin language itself and also about problem-solving in general. You don’t always know the answer to up-showing questions immediately and therefore have to put in some thoughts. This is always helpful and very valuable.

Give something back

What I also learned during that time is the fact that you shouldn’t always just take. In the case of StackOverflow, it’s almost disgraceful if you only read posts without telling the authors that their work helped you. I did the same for many years myself. You don’t need to feel bad about it but please take into consideration how much effort has been put into the questions and answers posted there. It really isn’t that hard to actually vote on these posts. If you don’t do this yet, create an account right away and give something back to the people you learn from.

Why you should start contributing

In my opinion, contributing to StackOverflow is a good thing for many reasons. It’s obvious that you’ll learn something from teaching and help others inescapably. Whatever topic you choose to participate in, you’ll be better at it afterward. More importantly, you’ll learn to value the contributions of the fellow answerers. You’ll recognize that it sucks if you don’t get up-voted by the people that consume your knowledge for free and you’ll probably never leave good answers (to the problems you searched for) without voting for them anymore. Even if you don’t want to answer questions, voting should be the least you should start with. If you’re willing to become an answerer though, I’d recommend choosing a niche topic like I did with Kotlin (which still needs expert contributors!). Entering tags like Java, on the other hand, is much more difficult because so many people are already involved in it.

Interestingly, I started a quick poll on Twitter which confirmed my assumptions: Most developers consume but don’t offer knowledge on StackOverflow.

twitter-stackoverflow-poll-s1m0nw1

I hope this makes sense and provokes a few readers to follow my advice.

EDIT:

I have to admit that I have experienced the StackOverflow community for just a short period of time and in the niche area of Kotlin, a language that still isn’t mainstream. I understand that StackOverflow is not just good and there are reasons you can criticise it for. If, after reading this article, you’re willing to learn from StackOverflow users, that have experienced the bad habits of the website, you should definitely read this post: My Love-Hate Relationship with StackOverflow.

Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂