Why every Android developer should use Anko

by: Adrián Bukros The post first appeared ✍🏼 on the Kotlin Development blog

Anko is an Android library written in Kotlin and maintained by JetBrains. The purpose of it is to speed up Android development with the capabilities of Kotlin, thus making it more convenient. That’s how it got its name. (An)droid (Ko)tlin. Let’s see what nice tools Anko has for us!

The Anko library has four main modules:

  • Commons
  • Layouts
  • SQLite
  • Coroutines

The commons module has a wide variety of helper functions and features. Using the layouts part of the library, you can create UI from Kotlin code with a feature called Anko DSL. The SQLite part of the library makes interacting with SQLite databases simpler. Last but not least, Anko provides a few helper functions for one of Kotlin 1.1 biggest feature: Kotlin coroutines.

Developing applications for the Android platform have never been easier.

In this article, I will focus exclusively on the Anko commons module.

Anko Commons

The most common

Let’s start with some basic simplifications! The View.setOnClickListener method is used everywhere in Android projects so it would be nice if we could make it more concise.
The longest form we can define a click handler in Kotlin:

button.setOnClickListener(object : View.OnClickListener{
override fun onClick(v: View) {
}
})

But Anko helps to minimize the effort we have to make:

button.onClick { }

The intentional

Using intents is one of the first things you will learn as an Android developer, but the API could be more convenient.

val intent = Intent(this, MainActivity::class.java)
intent.putExtra(“id”, 5)
intent.putExtra(“name”, “John”)
startActivity(intent)

Let’s see how could it be more simple:

startActivity<MainActivity>(“id” to 5, “name” to “John”)

One LOC instead of five. Not bad.
Also Anko has a few helper functions for common use cases regarding Intents:

browse(“https://makery.co")
share(“share”, “subject”)
email(“hello@makery.co”, “Great app idea”, “potato”)

Start a conversation with strangers more easily

Anko also makes the Android dialogs API more developer-friendly. No need for the builder pattern.

val builder = AlertDialog.Builder(this)
builder.setTitle(“Java”)
builder.setMessage(“Java is… old!”)
builder.setPositiveButton(“OK”) { dialog, which -> toast(“Yay!”) }
builder.setNegativeButton(“Cancel”) { dialog, which -> toast(“What?”) }
builder.show()
alert(Appcompat, “Kotlin”, “Kotlin is so fresh!”) {
customView { editText() }
positiveButton(“OK”) { toast(“Yay!”) }
negativeButton(“Cancel”) { toast(“What?”) }
}.show()

Size issues

Code size matters, also when doing dpi-maths programatically.
The complicated old way:

val dpAsPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10f, getResources().getDisplayMetrics())

The dead simple new way:

val dpAsPx = dip(10f)

Also you can get text sizes

sp(15f)

API level 23 (Paladin)

Fragmentation is a problem every Android developer has to face. We don’t want to leave anyone with older system versions behind, but we also want to use the cool new features of the latest Android releases.

What can we do? Branch our code. Usually it looks like this:

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP){ }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ }

Let’s see what Anko has for us:

doIfSdk(Build.VERSION_CODES.LOLLIPOP){ }
doFromSdk(Build.VERSION_CODES.LOLLIPOP){ }

I just had a snack at the snack bar.

The Android Snackbar API also could be better. Did you ever forget to call .show() after Snackbar.make() function, and then debug it for half an hour why it’s not showing? No? Maybe it’s just me.

Snackbar.make(findViewById(android.R.id.content), “This is a snack!”, Snackbar.LENGTH_LONG)
.show()

You don’t need to call show()!

longSnackbar(findViewById(android.R.id.content), “This is a snack!”)

If you are big fan of toasts, Anko also has something for you:

toast(“Message”)

Threading the needle

Handling multiple threads is not easy, but it’s a pretty common pattern in mobile development: most of the time we want to offload work from the UI thread. The way to do it with Anko is pretty straightforward and concise.

doAsync {
//IO task or other computation with high cpu load
uiThread {
toast(“async computation finished”)
}
}

Add Anko to your project

If you like the features above, what are you waiting for? It’s time to add Anko to your project!

ankoVersion = “0.10.1”
dependencies {
compile “org.jetbrains.anko:anko-appcompat-v7-listeners:$ankoVersion”
compile “org.jetbrains.anko:anko-design-listeners:$ankoVersion”
compile “org.jetbrains.anko:anko-design:$ankoVersion”
compile “org.jetbrains.anko:anko-sdk15-listeners:$ankoVersion”
compile “org.jetbrains.anko:anko-sdk15:$ankoVersion”
}

+1 Bye-bye findViewById()

Have you heard of the Kotlin Android Extensions Gradle plugin? You can get rid of all the hated findViewById() calls and casting Views by introducing one extra line to your Gradle script:

apply plugin: ‘kotlin-android-extensions’

Now you can just reference views from your XML files with their id.

// activity_main.xml

<LinearLayout 
xmlns:android=”http://schemas.android.com/apk/res/android"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:orientation=”vertical”>

<Button android:id=”@+id/button”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”OK”/>
</LinearLayout>

// MainActivity.kt

import kotlinx.android.synthetic.main.activity_main.*

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.onClick { }
}

Check out Kotlin Development.com for more interesting stories and code snippets written by real Kotlin devs from all around the globe! #hellokotlin

🌐 www.kotlindevelopment.com 
🐤 Twitter: @hellokotlin
📧 hello@kotlindevelopment.com