CODING FOR ANDROID ON STEROIDS
WITH KOTLIN
KAI KOENIG (@AGENTK)
AGENDA
▸ What is Kotlin?
▸ Language idioms & concepts
▸ Kotlin and Android
▸ Anko DSL
▸ Libraries and Tools
▸ Final thoughts
WHAT IS KOTLIN?
WHAT IS KOTLIN?
SOME FUNDAMENTALS
▸ Statically typed programming
language for the JVM and Android
▸ Started as internal language “Project
Kotlin” at Jetbrains in 2010
▸ Now: Open-Source, Apache License
▸ Kotlin SDK plus tool support for IntelliJ,
Android Studio, Eclipse
▸ Named after an island in the Gulf of
Finland
WHAT IS KOTLIN?
MOTIVATION FOR KOTLIN
▸ The Java platform is awesome, but it has its issues:
▸ sometimes tied to backwards/legacy compatibility
▸ can be a very verbose language and produce bloated code
▸ type system has various flaws
▸ Kotlin aims to fix a lot of those issues
▸ compiles to Java 6 byte code therefore caters well for Android runtimes
WHAT IS KOTLIN?
HOW DOES A SIMPLE CONVERSION LOOK LIKE?
public String listConvert(Collection<Integer>
collection) {
StringBuilder sb = new StringBuilder();
sb.append("{");
Iterator<Integer> iterator =
collection.iterator();
while (iterator.hasNext()) {
Integer element = iterator.next();
sb.append(element);
if (iterator.hasNext()) {
sb.append(", ");
}
}
sb.append("}");
return sb.toString();
}
fun listConvert(collection: Collection<Int>): String {
val sb = StringBuilder()
sb.append("{")
val iterator = collection.iterator()
while (iterator.hasNext()) {
val element = iterator.next()
sb.append(element)
if (iterator.hasNext()) {
sb.append(", ")
}
}
sb.append("}")
return sb.toString()
}
fun listConvertKt(collection: Collection<Int>): String {
return collection.joinToString(prefix = "{",postfix = "}")
}
LANGUAGE IDIOMS &
CONCEPTS
https://www.flickr.com/photos/geraldford/6976818221/
LANGUAGE IDIOMS & CONCEPTS
OVERVIEW
▸ Immutability
▸ String templates & Enum classes
▸ Null safety
▸ Properties and Fields
▸ Type inference and casts
▸ Data classes
▸ Syntactic sugar (loops, ranges etc)
▸ Extension functions
▸ Lambdas
▸ Collection API
▸ Type-safe builders
▸ Java-Kotlin-Interop
LANGUAGE IDIOMS & CONCEPTS
IMMUTABILITY
▸ Built-in support for mutable and
immutable variables, properties and
fields
▸ Keywords var and val
▸ val - immutable (recommended)
▸ var - mutable
▸ Similar concept applies for class
properties, val creates getters, var
creates getters and setters (more later)
val a: Int = 1
val b = 1
val c: Int
c = 1
var x = 23
x += 1
LANGUAGE IDIOMS & CONCEPTS
STRING TEMPLATES & ENUM CLASSES (I)
▸ Kotlin Strings can contain template
expressions
▸ String templates start with a $ character
and
▸ can contain simple references such
as $s, as well as
▸ complex expressions in curly braces: 

${s.length}
val s = "abc"
val str = "$s.length is ${s.length}"
Output:
abc.length is 3
LANGUAGE IDIOMS & CONCEPTS
STRING TEMPLATES & ENUM CLASSES (II)
▸ Kotlin has a dedicated and expressive
enum class
▸ Can be used very nicely in conjunction
with String templates
enum class Locale(val hello: String) {
DE_DE("Hallo"),
EN_NZ("Hello"),
MI_NZ("Kia Ora")
}
class Customer(val firstName:String,
val lastName:String,
val locale: Locale = Locale.DE_DE) {
fun sayHello() = println(
"${locale.hello}, $firstName $lastName")
}
fun main(args : Array<String>) {
val myCustomer = Customer("Sandra",
"Musterfrau",
Locale.MI_NZ)
myCustomer.sayHello()
}
LANGUAGE IDIOMS & CONCEPTS
NULL SAFETY
▸ Motivation: A better way to deal with NPEs
▸ Kotlin differentiates nullable types from non-
nullable types by adding a ? to the type:
▸ String: no nullable
▸ String?: nullable
▸ Handle manually
▸ Use Safe Call operator ?.
▸ Use the !! operator to allow/trigger a NPE
// Won't compile
var lastName: String = null
// Will compile
var lastNameNullable: String? = null
// Will also not compile
println(lastNameNullable.length)
// Option 1 (-1)
println(if (lastNameNullable != null)
lastNameNullable.length else -1)
// Option 2 (null)
println(lastNameNullable?.length)
// Option 3 (NPE)
println(lastNameNullable!!.length)
LANGUAGE IDIOMS & CONCEPTS
PROPERTIES AND FIELDS
▸ Kotlin classes have mutable or
immutable properties
▸ Default getter/setters for properties,
can be customised
▸ An automated backing field can be
provided by the compiler (if required)
▸ Alternative: use an explicit backing
property
var counter = 0
set(value) {
if (value >= 0)
field = value
}
public class Address {
public var name: String = ...
public var street: String = ...
public var city: String = ...
public var state: String? = ...
public var zip: String = ...
}
LANGUAGE IDIOMS & CONCEPTS
TYPE INFERENCE AND CASTS (I)
▸ When possible, Kotlin will infer the type
of variables
▸ Explicit conversions, type widening and
inference
▸ Smaller types are not subtypes of
bigger types, no implicit conversion
▸ Types are often inferred from the
context
val b: Byte = 1
// This won't work
val i: Int = b
// This will
val i: Int = b.toInt()
val l: Long = 1L + 3
LANGUAGE IDIOMS & CONCEPTS
TYPE INFERENCE AND CASTS (II)
▸ is or !is checks if an object adheres to a
certain type
▸ Smart cast: Compiler tracks is-expressions
for immutable values
▸ works for val local variables and private,
internal or in-module performed casts
▸ works for var local variables if the
variable hasn’t been modified between
check and usage, never for var
properties
fun whatIs(x: Any) {
when (x) {
is Int -> println(x + 42)
is String -> println(x.length)
is IntArray -> println(x.sum())
}
}
whatIs(4) // 46
whatIs("4") // 1
whatIs(intArrayOf(1,2,3,4,5)) // 15
LANGUAGE IDIOMS & CONCEPTS
DATA CLASSES
▸ The POJOs/Beans of other languages
▸ Data classes implicitly create:
▸ getters/setters (non-data classes
have those too) - recommend to use
val as often as possible.
▸ useful implementations for equals(),
hashCode(), toString(), copy()
▸ copy() has default parameters and
can be used to alter a copy
data class ChromeEncryptedPayload(
val encryptedPayload: String,
val encryptionHeader: String,
val cryptoKeyHeader: String)
val pl = ChromeEncryptedPayload(
encryptedPayload = "...",
encryptionHeader = "...",
cryptoKeyHeader = "...")
val anotherPl = pl.copy(
encryptedPayload = "...")
LANGUAGE IDIOMS & CONCEPTS
EXTENSION FUNCTIONS
▸ Allow adding new functionality to a
class without inheritance or Decorators
▸ Kotlin has extension functions as well
as extension properties
▸ Resolved statically, don’t actually
modify the class (excellent example
why this has to be the case at http://
goo.gl/EN6bTs
fun Int.sum(otherInt: Int): Int =
this + otherInt
3.sum(7)
fun Activity.toast(message: CharSequence,
duration: Int =
TOAST.LENGTH_SHORT) {
Toast.makeText(this, message,
duration).show()
}
// In onCreate of an Activity
override fun onCreate(...) {
...
toast("Hi there")
...
}
LANGUAGE IDIOMS & CONCEPTS
LAMBDAS
▸ Anonymous function or “function
literal”, closely related to the ideas of
Higher-Order-Functions
val sum = { x: Int, y: Int -> x + y }
val sum: (Int, Int) -> Int = { x, y ->
x + y }
private fun convertPetListToDomain(list: List<Pet>): List<PetDomain> {
return list.map { convertPetItemToDomain(it) }
}
private fun convertPetItemToDomain(pet: Pet): PetDomain {
return PetDomain(pet.age,pet.size,pet.id,pet.name,pet.sex,pet.breed)
}
LANGUAGE IDIOMS & CONCEPTS
TYPE-SAFE BUILDERS (I)
▸ Builders are a very popular approach in
Groovy to define data in a declarative
way
▸ Often used for:
▸ generating XML or JSON
▸ UI layout (Swing components) etc
▸ In Kotlin, builders even can be type-
checked
JsonBuilder builder = new JsonBuilder()
builder.records {
car {
name 'HSV Maloo'
make 'Holden'
year 2006
country 'Australia'
}
}
String json = JsonOutput.prettyPrint
(builder.toString())
LANGUAGE IDIOMS & CONCEPTS
TYPE-SAFE BUILDERS (II)
▸ html() is a function with a lambda as an
argument (init)
▸ init’s type is a function type with
receiver, this allows you to:
▸ pass receiver (of type HTML) to
function
▸ call members of instance inside the
function
fun result(args: Array<String>) =
html {
head {
title {”HTML in Kotlin"}
}
body {
...
}
}
fun html(init: HTML.() -> Unit): HTML {
val html = HTML()
html.init()
return html
}
LANGUAGE IDIOMS & CONCEPTS
TYPE-SAFE BUILDERS (III)
▸ HTML class has functions to build the
head and the body elements of the
DSL.
▸ Not shown: classes further down in the
hierarchy:
▸ Head, Body etc.
▸ Complete HTML builder example at:
http://goo.gl/TndcC9
class HTML {
...
fun head(headBuilder: Head.() -> Unit) {
head = Head()
head?.headBuilder()
}
fun body(bodyBuilder: Body.() -> Unit) {
body = Body()
body?.bodyBuilder()
}
}
LANGUAGE IDIOMS & CONCEPTS
JAVA-KOTLIN-INTEROP
▸ Java and Kotlin are fully interoperable from an integration point of view
▸ Your Java code can call and use Kotlin code
▸ Your Kotlin code can call and use Java code
▸ The latter is in particular useful because it means you can continue to use pretty
much any existing Android/Java library
▸ Check out Hendrik Kokocinski’s sample Kotlin app that uses all kinds of well
known Android/Java libs: https://goo.gl/xdYqf5
LANGUAGE IDIOMS & CONCEPTS
OVERVIEW
▸ Immutability
▸ String templates & Enum classes
▸ Null safety
▸ Properties and Fields
▸ Type inference and casts
▸ Data classes
▸ Syntactic sugar (loops, ranges etc)
▸ Extension functions
▸ Lambdas
▸ Collection API
▸ Type-safe builders
▸ Java-Kotlin-Interop
KOTLIN AND ANDROID
https://realm.io/assets/img/news/tutorial-kotlin-anko-cover.png
KOTLIN AND ANDROID
TOOLCHAIN AND FLOW
Java sourcesKotlin sources
Bytecode
javackotlinc
Dalvik ART JVM
KOTLIN AND ANDROID
PROJECT SETUP
▸ Use Android Studio 2.x or IntelliJ 2016
▸ Install Kotlin plugin (comes within “Jetbrains plugins”)
▸ Gradle dependencies project-level:
▸ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.4"
▸ Gradle dependencies module-level:
▸ compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.4'
▸ apply plugin: 'kotlin-android'
▸ main.java.srcDirs += 'src/main/kotlin'
KOTLIN AND ANDROID
KOTLIN EXTENSIONS FOR ANDROID
▸ Provides of a set of synthetic properties that bind views to those properties
▸ Alternative to Butter Knife-style bindings, no need for additional runtime
library (Kotlin Extensions for Android are a Kotlin compiler plugin)
▸ import kotlinx.android.synthetic.main.<layout>.*
▸ import kotlinx.android.synthetic.main.<layout>
▸ usage: <componentid>.doSomething()
KOTLIN AND ANDROID
SYNTHETIC PROPERTIES
package ventegocreative.co.nz.kotlindemo
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
helloworld.text = "Hey, I'm dynamically set"
}
}
ANKO DSL
ANKO DSL
WHAT IS A DSL?
▸ Domain-Specific Language
▸ Limited expressiveness:
▸ DSLs are usually not general-purpose languages
▸ strongly focussed on a particular domain
▸ examples: SQL, Ant XML, XSLT, Gradle etc.
ANKO DSL
A DSL FOR LAYOUTS
▸ The most important element of Anko is the Layout DSL
▸ Idea: replace XML layout definitions by Kotlin code - without having to build
the layout in a fully programmatic sense
▸ Anko DSL is modular and extensible
ANKO DSL
LAYOUT XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:gravity="center"
android:text="@string/empty_todos_message"
android:layout_weight="7"
android:layout_height="wrap_content" />
<Button
android:layout_width="match_parent"
android:layout_weight="1"
android:text="Say Hello"
android:layout_height="0dp" />
</LinearLayout>
ANKO DSL
PROGRAMMATIC LAYOUT IN KOTLIN
val act = this
val layout = LinearLayout(act)
layout.orientation = LinearLayout.VERTICAL
val name = EditText(act)
val button = Button(act)
button.text = "Say Hello"
button.setOnClickListener {
Toast.makeText(act, "Hello, ${name.text}!", Toast.LENGTH_SHORT).show()
}
layout.addView(name)
layout.addView(button)
ANKO DSL
ANKO DSL
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
ANKO DSL
ANKO DSL INTERNALS
▸ Anko DSL example from previous slide looks very similar to the earlier HTML
builder example
▸ Anko uses extension functions arranged into type-safe builders and lambdas
▸ You don’t have to write all those extensions by hand though - Anko generates
them based on the Android SDK’s android.jar
ANKO DSL
GETTING STARTED WITH ANKO DSL (I)
▸ Depending on minSdkVersion of project, import:

compile "org.jetbrains.anko:anko-sdk{15|19|21|23}:0.9"
▸ If the project uses an Android Support library, import matching Anko library:

compile "org.jetbrains.anko:anko-recyclerview-v7:0.9"
ANKO DSL
GETTING STARTED WITH ANKO DSL (II)
▸ General approach:
▸ Anko DSL automatically becomes
available in onCreate() in an Activity
▸ no need for setContentView(), Anko
DSL also automatically sets the
content view for activities
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
padding = dip(30)
editText {
hint = "Name"
textSize = 24f
}
editText {
hint = "Password"
textSize = 24f
}
button("Login") {
textSize = 26f
}
}
}
ANKO DSL
ANKO DSL IN FRAGMENTS
▸ In fragments, use 

onCreateView(…)
▸ Returns UI {…}.view:
▸ mandatory before Anko 0.8
▸ works well for Fragments
▸ createTodo() is a fragment-private
method
override fun onCreateView(inflater: LayoutInflater?,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return UI {
verticalLayout {
padding = dip(24)
var title = editText {
id = R.id.title
hintResource = R.string.hint
}
...
button {
id = R.id.add
textResource = R.string.add
onClick { view -> createTodo(title, desc) }
}
}
}.view
}
ANKO DSL
ANKO COMPONENTS
class EditFragmentUI : AnkoComponent<EditFragment> {
override fun createView(ui: AnkoContext<EditFragment>) = with(ui) {
verticalLayout {
padding = dip(24)
var title = editText {
id = R.id.title
hintResource = R.string.hint
}
...
button {
id = R.id.add
textResource = R.string.add
onClick { view -> ui.owner.createTodoFrom(title, desc) }
}
}
}
}
override fun onCreateView(...)= EditFragmentUI().createView(AnkoContext.create(ctx,this))
ANKO DSL
EXTENDING ANKOS DSL FUNCTIONALITY
▸ Multiple ways to do this:
▸ insert an existing XML layout into an Anko DSL declaration:

▸ adding new DSL elements to the language
include<View>(R.layout.mylayout) { ... }
inline fun ViewManager.customView(theme: Int = 0) = customView(theme) {}
inline fun ViewManager.customView(theme: Int = 0, init: CustomView.() -> Unit) =
ankoView({ CustomView(it) }, theme, init)
inline fun Activity.customView(theme: Int = 0) = customView(theme) {}
inline fun Activity.customView(theme: Int = 0, init: CustomView.() -> Unit) =
ankoView({ CustomView(it) }, theme, init)
ANKO DSL
THERE’S MORE
▸ Intent wrappers for various purposes: e.g. sendSMS(number, [text])
▸ Intent builders
▸ Service shortcuts
▸ Configuration qualifiers: configuration(screenSize = ScreenSize.LARGE,
orientation = Orientation.LANDSCAPE) { … }
▸ Asynchronous tasks
▸ SQLLite
LIBRARIES AND TOOLS
https://www.flickr.com/photos/sillygwailo/5990089210/
LIBRARIES AND TOOLS
OVERVIEW
▸ Kotter Knife
▸ Butter Knife
▸ KAndroid
▸ Kovenant
▸ Fuel, Injekt, Spek, Kotson
LIBRARIES AND TOOLS
KOTTER KNIFE (AND BUTTER KNIFE)
▸ Kotter Knife provides view binding in a similar way to Butter Knife for Android/
Java
▸ Why *Knife over KAE?
▸ Porting code from Java/Butter Knife to Kotlin
▸ Features like listener binding and resources binding that don’t exist in KAE.
▸ Sample code for Butter Knife/Kotlin in the official Jetbrains Kotlin Examples repo
(https://goo.gl/rH7vBu)
LIBRARIES AND TOOLS
KOTTER KNIFE VS BUTTER KNIFE VS KAE (I)
findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("MainActivity", "onClick: send")
}
});
@OnClick(R.id.send)
void clickSend(View v) {
Log.d("MainActivity", "onClick: send")
}
LIBRARIES AND TOOLS
KOTTER KNIFE VS BUTTER KNIFE VS KAE (II)
findViewById(R.id.send).setOnClickListener { view -> Log.d("MainActivity",
"onClick: send") };
val btnSend: Button by bindView(R.id.send)
btnSend.setOnClickListener({ view -> Log.d("MainActivity", "onClick: send") })
import kotlinx.android.synthetic.activity_main.*
btn_send.setOnClickListener({ view -> Log.d("MainActivity", "onClick: send") })
LIBRARIES AND TOOLS
KANDROID
▸ View binding (again)
▸ TextWatcher
▸ SeekBar Extension
▸ SearchView Extension
▸ Shortcuts to system services
▸ Logging
▸ Dealing with Intents
▸ SDK Version API (from/to)
▸ Thread management
LIBRARIES AND TOOLS
KOVENANT
▸ Core: foundations of a Promise
framework
▸ Tasks & Callbacks
▸ Chaining (Then, ThenApply)
▸ Lazy Promises
▸ Cancelling and Voiding
▸ Combine: combines 2-20 promises
▸ Functional: adds map, bind and
apply to support more advanced
HOF constructs in Kovenant
▸ JVM: Executors and Throttles (thread
pools)
▸ Android: UI callbacks and interacting
with UI Thread
LIBRARIES AND TOOLS
OVERVIEW
▸ Kotter Knife
▸ Butter Knife
▸ KAndroid
▸ Kovenant
▸ Fuel, Injekt, Spek, Kotson
FINAL THOUGHTS
https://www.flickr.com/photos/brickset/16099265973/
FINAL THOUGHTS
PERFORMANCE
▸ Runtime is pretty much on-par with Java
▸ Pre Kotlin 1.0.2: Build process was slower than a comparable app in Java -
mainly due to how the Kotlin compiler works (no partial builds/compilation)
▸ Kotlin libraries do add to the size of the application as well as to the method
count
▸ Kotlin runtime + stdlib are similar in method count to support-v4 or play-
services-base and add significantly less than Scala or Groovy
FINAL THOUGHTS
LANGUAGE AND MATURITY
▸ Kotlin 1.0 was a big step for the language
▸ Surprisingly mature for a 1.0 release (but 5+ years in the making), full of great
concepts and idioms, getting better with each release
▸ Anko is very stable given it’s still a 0.x release
▸ Anko makes UI declaration actually pleasurable but offers way more than only
a layout DSL
FINAL THOUGHTS
WHAT DID WE LEARN?
▸ What is Kotlin?
▸ Language idioms & concepts
▸ Kotlin and Android
▸ Anko DSL
▸ Libraries and Tools
▸ Final thoughts
RESOURCES
RESOURCES
▸ Kotlin: http://kotlinlang.org
▸ Anko: https://github.com/Kotlin/anko
▸ Kotter Knife: https://github.com/JakeWharton/kotterknife
▸ KAndroid: https://github.com/pawegio/KAndroid
▸ Kovenant: https://github.com/mplatvoet/kovenant
▸ Fuel: https://github.com/kittinunf/Fuel
▸ Injekt: https://github.com/kohesive/injekt
▸ Spek: http://jetbrains.github.io/spek/
▸ Kotson: https://github.com/SalomonBrys/Kotson
RESOURCES
GET IN TOUCH
Kai Koenig
Email: kai@ventego-creative.co.nz
Twitter: @AgentK

Coding for Android on steroids with Kotlin

  • 1.
    CODING FOR ANDROIDON STEROIDS WITH KOTLIN KAI KOENIG (@AGENTK)
  • 2.
    AGENDA ▸ What isKotlin? ▸ Language idioms & concepts ▸ Kotlin and Android ▸ Anko DSL ▸ Libraries and Tools ▸ Final thoughts
  • 3.
  • 4.
    WHAT IS KOTLIN? SOMEFUNDAMENTALS ▸ Statically typed programming language for the JVM and Android ▸ Started as internal language “Project Kotlin” at Jetbrains in 2010 ▸ Now: Open-Source, Apache License ▸ Kotlin SDK plus tool support for IntelliJ, Android Studio, Eclipse ▸ Named after an island in the Gulf of Finland
  • 5.
    WHAT IS KOTLIN? MOTIVATIONFOR KOTLIN ▸ The Java platform is awesome, but it has its issues: ▸ sometimes tied to backwards/legacy compatibility ▸ can be a very verbose language and produce bloated code ▸ type system has various flaws ▸ Kotlin aims to fix a lot of those issues ▸ compiles to Java 6 byte code therefore caters well for Android runtimes
  • 6.
    WHAT IS KOTLIN? HOWDOES A SIMPLE CONVERSION LOOK LIKE? public String listConvert(Collection<Integer> collection) { StringBuilder sb = new StringBuilder(); sb.append("{"); Iterator<Integer> iterator = collection.iterator(); while (iterator.hasNext()) { Integer element = iterator.next(); sb.append(element); if (iterator.hasNext()) { sb.append(", "); } } sb.append("}"); return sb.toString(); } fun listConvert(collection: Collection<Int>): String { val sb = StringBuilder() sb.append("{") val iterator = collection.iterator() while (iterator.hasNext()) { val element = iterator.next() sb.append(element) if (iterator.hasNext()) { sb.append(", ") } } sb.append("}") return sb.toString() } fun listConvertKt(collection: Collection<Int>): String { return collection.joinToString(prefix = "{",postfix = "}") }
  • 7.
  • 8.
    LANGUAGE IDIOMS &CONCEPTS OVERVIEW ▸ Immutability ▸ String templates & Enum classes ▸ Null safety ▸ Properties and Fields ▸ Type inference and casts ▸ Data classes ▸ Syntactic sugar (loops, ranges etc) ▸ Extension functions ▸ Lambdas ▸ Collection API ▸ Type-safe builders ▸ Java-Kotlin-Interop
  • 9.
    LANGUAGE IDIOMS &CONCEPTS IMMUTABILITY ▸ Built-in support for mutable and immutable variables, properties and fields ▸ Keywords var and val ▸ val - immutable (recommended) ▸ var - mutable ▸ Similar concept applies for class properties, val creates getters, var creates getters and setters (more later) val a: Int = 1 val b = 1 val c: Int c = 1 var x = 23 x += 1
  • 10.
    LANGUAGE IDIOMS &CONCEPTS STRING TEMPLATES & ENUM CLASSES (I) ▸ Kotlin Strings can contain template expressions ▸ String templates start with a $ character and ▸ can contain simple references such as $s, as well as ▸ complex expressions in curly braces: 
 ${s.length} val s = "abc" val str = "$s.length is ${s.length}" Output: abc.length is 3
  • 11.
    LANGUAGE IDIOMS &CONCEPTS STRING TEMPLATES & ENUM CLASSES (II) ▸ Kotlin has a dedicated and expressive enum class ▸ Can be used very nicely in conjunction with String templates enum class Locale(val hello: String) { DE_DE("Hallo"), EN_NZ("Hello"), MI_NZ("Kia Ora") } class Customer(val firstName:String, val lastName:String, val locale: Locale = Locale.DE_DE) { fun sayHello() = println( "${locale.hello}, $firstName $lastName") } fun main(args : Array<String>) { val myCustomer = Customer("Sandra", "Musterfrau", Locale.MI_NZ) myCustomer.sayHello() }
  • 12.
    LANGUAGE IDIOMS &CONCEPTS NULL SAFETY ▸ Motivation: A better way to deal with NPEs ▸ Kotlin differentiates nullable types from non- nullable types by adding a ? to the type: ▸ String: no nullable ▸ String?: nullable ▸ Handle manually ▸ Use Safe Call operator ?. ▸ Use the !! operator to allow/trigger a NPE // Won't compile var lastName: String = null // Will compile var lastNameNullable: String? = null // Will also not compile println(lastNameNullable.length) // Option 1 (-1) println(if (lastNameNullable != null) lastNameNullable.length else -1) // Option 2 (null) println(lastNameNullable?.length) // Option 3 (NPE) println(lastNameNullable!!.length)
  • 13.
    LANGUAGE IDIOMS &CONCEPTS PROPERTIES AND FIELDS ▸ Kotlin classes have mutable or immutable properties ▸ Default getter/setters for properties, can be customised ▸ An automated backing field can be provided by the compiler (if required) ▸ Alternative: use an explicit backing property var counter = 0 set(value) { if (value >= 0) field = value } public class Address { public var name: String = ... public var street: String = ... public var city: String = ... public var state: String? = ... public var zip: String = ... }
  • 14.
    LANGUAGE IDIOMS &CONCEPTS TYPE INFERENCE AND CASTS (I) ▸ When possible, Kotlin will infer the type of variables ▸ Explicit conversions, type widening and inference ▸ Smaller types are not subtypes of bigger types, no implicit conversion ▸ Types are often inferred from the context val b: Byte = 1 // This won't work val i: Int = b // This will val i: Int = b.toInt() val l: Long = 1L + 3
  • 15.
    LANGUAGE IDIOMS &CONCEPTS TYPE INFERENCE AND CASTS (II) ▸ is or !is checks if an object adheres to a certain type ▸ Smart cast: Compiler tracks is-expressions for immutable values ▸ works for val local variables and private, internal or in-module performed casts ▸ works for var local variables if the variable hasn’t been modified between check and usage, never for var properties fun whatIs(x: Any) { when (x) { is Int -> println(x + 42) is String -> println(x.length) is IntArray -> println(x.sum()) } } whatIs(4) // 46 whatIs("4") // 1 whatIs(intArrayOf(1,2,3,4,5)) // 15
  • 16.
    LANGUAGE IDIOMS &CONCEPTS DATA CLASSES ▸ The POJOs/Beans of other languages ▸ Data classes implicitly create: ▸ getters/setters (non-data classes have those too) - recommend to use val as often as possible. ▸ useful implementations for equals(), hashCode(), toString(), copy() ▸ copy() has default parameters and can be used to alter a copy data class ChromeEncryptedPayload( val encryptedPayload: String, val encryptionHeader: String, val cryptoKeyHeader: String) val pl = ChromeEncryptedPayload( encryptedPayload = "...", encryptionHeader = "...", cryptoKeyHeader = "...") val anotherPl = pl.copy( encryptedPayload = "...")
  • 17.
    LANGUAGE IDIOMS &CONCEPTS EXTENSION FUNCTIONS ▸ Allow adding new functionality to a class without inheritance or Decorators ▸ Kotlin has extension functions as well as extension properties ▸ Resolved statically, don’t actually modify the class (excellent example why this has to be the case at http:// goo.gl/EN6bTs fun Int.sum(otherInt: Int): Int = this + otherInt 3.sum(7) fun Activity.toast(message: CharSequence, duration: Int = TOAST.LENGTH_SHORT) { Toast.makeText(this, message, duration).show() } // In onCreate of an Activity override fun onCreate(...) { ... toast("Hi there") ... }
  • 18.
    LANGUAGE IDIOMS &CONCEPTS LAMBDAS ▸ Anonymous function or “function literal”, closely related to the ideas of Higher-Order-Functions val sum = { x: Int, y: Int -> x + y } val sum: (Int, Int) -> Int = { x, y -> x + y } private fun convertPetListToDomain(list: List<Pet>): List<PetDomain> { return list.map { convertPetItemToDomain(it) } } private fun convertPetItemToDomain(pet: Pet): PetDomain { return PetDomain(pet.age,pet.size,pet.id,pet.name,pet.sex,pet.breed) }
  • 19.
    LANGUAGE IDIOMS &CONCEPTS TYPE-SAFE BUILDERS (I) ▸ Builders are a very popular approach in Groovy to define data in a declarative way ▸ Often used for: ▸ generating XML or JSON ▸ UI layout (Swing components) etc ▸ In Kotlin, builders even can be type- checked JsonBuilder builder = new JsonBuilder() builder.records { car { name 'HSV Maloo' make 'Holden' year 2006 country 'Australia' } } String json = JsonOutput.prettyPrint (builder.toString())
  • 20.
    LANGUAGE IDIOMS &CONCEPTS TYPE-SAFE BUILDERS (II) ▸ html() is a function with a lambda as an argument (init) ▸ init’s type is a function type with receiver, this allows you to: ▸ pass receiver (of type HTML) to function ▸ call members of instance inside the function fun result(args: Array<String>) = html { head { title {”HTML in Kotlin"} } body { ... } } fun html(init: HTML.() -> Unit): HTML { val html = HTML() html.init() return html }
  • 21.
    LANGUAGE IDIOMS &CONCEPTS TYPE-SAFE BUILDERS (III) ▸ HTML class has functions to build the head and the body elements of the DSL. ▸ Not shown: classes further down in the hierarchy: ▸ Head, Body etc. ▸ Complete HTML builder example at: http://goo.gl/TndcC9 class HTML { ... fun head(headBuilder: Head.() -> Unit) { head = Head() head?.headBuilder() } fun body(bodyBuilder: Body.() -> Unit) { body = Body() body?.bodyBuilder() } }
  • 22.
    LANGUAGE IDIOMS &CONCEPTS JAVA-KOTLIN-INTEROP ▸ Java and Kotlin are fully interoperable from an integration point of view ▸ Your Java code can call and use Kotlin code ▸ Your Kotlin code can call and use Java code ▸ The latter is in particular useful because it means you can continue to use pretty much any existing Android/Java library ▸ Check out Hendrik Kokocinski’s sample Kotlin app that uses all kinds of well known Android/Java libs: https://goo.gl/xdYqf5
  • 23.
    LANGUAGE IDIOMS &CONCEPTS OVERVIEW ▸ Immutability ▸ String templates & Enum classes ▸ Null safety ▸ Properties and Fields ▸ Type inference and casts ▸ Data classes ▸ Syntactic sugar (loops, ranges etc) ▸ Extension functions ▸ Lambdas ▸ Collection API ▸ Type-safe builders ▸ Java-Kotlin-Interop
  • 24.
  • 25.
    KOTLIN AND ANDROID TOOLCHAINAND FLOW Java sourcesKotlin sources Bytecode javackotlinc Dalvik ART JVM
  • 26.
    KOTLIN AND ANDROID PROJECTSETUP ▸ Use Android Studio 2.x or IntelliJ 2016 ▸ Install Kotlin plugin (comes within “Jetbrains plugins”) ▸ Gradle dependencies project-level: ▸ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.4" ▸ Gradle dependencies module-level: ▸ compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.4' ▸ apply plugin: 'kotlin-android' ▸ main.java.srcDirs += 'src/main/kotlin'
  • 27.
    KOTLIN AND ANDROID KOTLINEXTENSIONS FOR ANDROID ▸ Provides of a set of synthetic properties that bind views to those properties ▸ Alternative to Butter Knife-style bindings, no need for additional runtime library (Kotlin Extensions for Android are a Kotlin compiler plugin) ▸ import kotlinx.android.synthetic.main.<layout>.* ▸ import kotlinx.android.synthetic.main.<layout> ▸ usage: <componentid>.doSomething()
  • 28.
    KOTLIN AND ANDROID SYNTHETICPROPERTIES package ventegocreative.co.nz.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) helloworld.text = "Hey, I'm dynamically set" } }
  • 29.
  • 30.
    ANKO DSL WHAT ISA DSL? ▸ Domain-Specific Language ▸ Limited expressiveness: ▸ DSLs are usually not general-purpose languages ▸ strongly focussed on a particular domain ▸ examples: SQL, Ant XML, XSLT, Gradle etc.
  • 31.
    ANKO DSL A DSLFOR LAYOUTS ▸ The most important element of Anko is the Layout DSL ▸ Idea: replace XML layout definitions by Kotlin code - without having to build the layout in a fully programmatic sense ▸ Anko DSL is modular and extensible
  • 32.
    ANKO DSL LAYOUT XML <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="match_parent" android:gravity="center" android:text="@string/empty_todos_message" android:layout_weight="7" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:layout_weight="1" android:text="Say Hello" android:layout_height="0dp" /> </LinearLayout>
  • 33.
    ANKO DSL PROGRAMMATIC LAYOUTIN KOTLIN val act = this val layout = LinearLayout(act) layout.orientation = LinearLayout.VERTICAL val name = EditText(act) val button = Button(act) button.text = "Say Hello" button.setOnClickListener { Toast.makeText(act, "Hello, ${name.text}!", Toast.LENGTH_SHORT).show() } layout.addView(name) layout.addView(button)
  • 34.
    ANKO DSL ANKO DSL verticalLayout{ val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } }
  • 35.
    ANKO DSL ANKO DSLINTERNALS ▸ Anko DSL example from previous slide looks very similar to the earlier HTML builder example ▸ Anko uses extension functions arranged into type-safe builders and lambdas ▸ You don’t have to write all those extensions by hand though - Anko generates them based on the Android SDK’s android.jar
  • 36.
    ANKO DSL GETTING STARTEDWITH ANKO DSL (I) ▸ Depending on minSdkVersion of project, import:
 compile "org.jetbrains.anko:anko-sdk{15|19|21|23}:0.9" ▸ If the project uses an Android Support library, import matching Anko library:
 compile "org.jetbrains.anko:anko-recyclerview-v7:0.9"
  • 37.
    ANKO DSL GETTING STARTEDWITH ANKO DSL (II) ▸ General approach: ▸ Anko DSL automatically becomes available in onCreate() in an Activity ▸ no need for setContentView(), Anko DSL also automatically sets the content view for activities override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) verticalLayout { padding = dip(30) editText { hint = "Name" textSize = 24f } editText { hint = "Password" textSize = 24f } button("Login") { textSize = 26f } } }
  • 38.
    ANKO DSL ANKO DSLIN FRAGMENTS ▸ In fragments, use 
 onCreateView(…) ▸ Returns UI {…}.view: ▸ mandatory before Anko 0.8 ▸ works well for Fragments ▸ createTodo() is a fragment-private method override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { return UI { verticalLayout { padding = dip(24) var title = editText { id = R.id.title hintResource = R.string.hint } ... button { id = R.id.add textResource = R.string.add onClick { view -> createTodo(title, desc) } } } }.view }
  • 39.
    ANKO DSL ANKO COMPONENTS classEditFragmentUI : AnkoComponent<EditFragment> { override fun createView(ui: AnkoContext<EditFragment>) = with(ui) { verticalLayout { padding = dip(24) var title = editText { id = R.id.title hintResource = R.string.hint } ... button { id = R.id.add textResource = R.string.add onClick { view -> ui.owner.createTodoFrom(title, desc) } } } } } override fun onCreateView(...)= EditFragmentUI().createView(AnkoContext.create(ctx,this))
  • 40.
    ANKO DSL EXTENDING ANKOSDSL FUNCTIONALITY ▸ Multiple ways to do this: ▸ insert an existing XML layout into an Anko DSL declaration:
 ▸ adding new DSL elements to the language include<View>(R.layout.mylayout) { ... } inline fun ViewManager.customView(theme: Int = 0) = customView(theme) {} inline fun ViewManager.customView(theme: Int = 0, init: CustomView.() -> Unit) = ankoView({ CustomView(it) }, theme, init) inline fun Activity.customView(theme: Int = 0) = customView(theme) {} inline fun Activity.customView(theme: Int = 0, init: CustomView.() -> Unit) = ankoView({ CustomView(it) }, theme, init)
  • 41.
    ANKO DSL THERE’S MORE ▸Intent wrappers for various purposes: e.g. sendSMS(number, [text]) ▸ Intent builders ▸ Service shortcuts ▸ Configuration qualifiers: configuration(screenSize = ScreenSize.LARGE, orientation = Orientation.LANDSCAPE) { … } ▸ Asynchronous tasks ▸ SQLLite
  • 42.
  • 43.
    LIBRARIES AND TOOLS OVERVIEW ▸Kotter Knife ▸ Butter Knife ▸ KAndroid ▸ Kovenant ▸ Fuel, Injekt, Spek, Kotson
  • 44.
    LIBRARIES AND TOOLS KOTTERKNIFE (AND BUTTER KNIFE) ▸ Kotter Knife provides view binding in a similar way to Butter Knife for Android/ Java ▸ Why *Knife over KAE? ▸ Porting code from Java/Butter Knife to Kotlin ▸ Features like listener binding and resources binding that don’t exist in KAE. ▸ Sample code for Butter Knife/Kotlin in the official Jetbrains Kotlin Examples repo (https://goo.gl/rH7vBu)
  • 45.
    LIBRARIES AND TOOLS KOTTERKNIFE VS BUTTER KNIFE VS KAE (I) findViewById(R.id.send).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("MainActivity", "onClick: send") } }); @OnClick(R.id.send) void clickSend(View v) { Log.d("MainActivity", "onClick: send") }
  • 46.
    LIBRARIES AND TOOLS KOTTERKNIFE VS BUTTER KNIFE VS KAE (II) findViewById(R.id.send).setOnClickListener { view -> Log.d("MainActivity", "onClick: send") }; val btnSend: Button by bindView(R.id.send) btnSend.setOnClickListener({ view -> Log.d("MainActivity", "onClick: send") }) import kotlinx.android.synthetic.activity_main.* btn_send.setOnClickListener({ view -> Log.d("MainActivity", "onClick: send") })
  • 47.
    LIBRARIES AND TOOLS KANDROID ▸View binding (again) ▸ TextWatcher ▸ SeekBar Extension ▸ SearchView Extension ▸ Shortcuts to system services ▸ Logging ▸ Dealing with Intents ▸ SDK Version API (from/to) ▸ Thread management
  • 48.
    LIBRARIES AND TOOLS KOVENANT ▸Core: foundations of a Promise framework ▸ Tasks & Callbacks ▸ Chaining (Then, ThenApply) ▸ Lazy Promises ▸ Cancelling and Voiding ▸ Combine: combines 2-20 promises ▸ Functional: adds map, bind and apply to support more advanced HOF constructs in Kovenant ▸ JVM: Executors and Throttles (thread pools) ▸ Android: UI callbacks and interacting with UI Thread
  • 49.
    LIBRARIES AND TOOLS OVERVIEW ▸Kotter Knife ▸ Butter Knife ▸ KAndroid ▸ Kovenant ▸ Fuel, Injekt, Spek, Kotson
  • 50.
  • 51.
    FINAL THOUGHTS PERFORMANCE ▸ Runtimeis pretty much on-par with Java ▸ Pre Kotlin 1.0.2: Build process was slower than a comparable app in Java - mainly due to how the Kotlin compiler works (no partial builds/compilation) ▸ Kotlin libraries do add to the size of the application as well as to the method count ▸ Kotlin runtime + stdlib are similar in method count to support-v4 or play- services-base and add significantly less than Scala or Groovy
  • 52.
    FINAL THOUGHTS LANGUAGE ANDMATURITY ▸ Kotlin 1.0 was a big step for the language ▸ Surprisingly mature for a 1.0 release (but 5+ years in the making), full of great concepts and idioms, getting better with each release ▸ Anko is very stable given it’s still a 0.x release ▸ Anko makes UI declaration actually pleasurable but offers way more than only a layout DSL
  • 53.
    FINAL THOUGHTS WHAT DIDWE LEARN? ▸ What is Kotlin? ▸ Language idioms & concepts ▸ Kotlin and Android ▸ Anko DSL ▸ Libraries and Tools ▸ Final thoughts
  • 54.
    RESOURCES RESOURCES ▸ Kotlin: http://kotlinlang.org ▸Anko: https://github.com/Kotlin/anko ▸ Kotter Knife: https://github.com/JakeWharton/kotterknife ▸ KAndroid: https://github.com/pawegio/KAndroid ▸ Kovenant: https://github.com/mplatvoet/kovenant ▸ Fuel: https://github.com/kittinunf/Fuel ▸ Injekt: https://github.com/kohesive/injekt ▸ Spek: http://jetbrains.github.io/spek/ ▸ Kotson: https://github.com/SalomonBrys/Kotson
  • 55.
    RESOURCES GET IN TOUCH KaiKoenig Email: [email protected] Twitter: @AgentK