Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Coding for Android on steroids with Kotlin

1,018 views

Published on

Kotlin is a new language for the JVM that aims to be a "better Java". Made in-house by Jetbrains, the company behind IntelliJ IDEA and also Android Studio, it's been in development for more than 5 years. Just a few weeks ago the final version of Kotlin 1.0 saw the light of day.

This talk will start with a brief introduction into Kotlin and its core language features. After this brief foray into concepts like Kotlin's immutable variables, null behaviour and other smarts like the syntactic sugar it provides for dealing with types and properties you'll discover what's in store for Android developers.

Particularly noteworthy are the decrease in annoying Java boilerplate code, fewer of the irritating "Process has stopped unexpectedly" messages and the easily available Kotlin Android Extensions. You will also explore the toolchain and compiler tools Kotlin provides for Android development, the differences to using Kotlin for Java development as well as the integration into Android Studio.

Published in: Software
  • Be the first to comment

Coding for Android on steroids with Kotlin

  1. 1. CODING FOR ANDROID ON STEROIDS WITH KOTLIN KAI KOENIG (@AGENTK)
  2. 2. AGENDA ▸ What is Kotlin? ▸ Language idioms & concepts ▸ Kotlin and Android ▸ Anko DSL ▸ Libraries and Tools ▸ Final thoughts
  3. 3. WHAT IS KOTLIN?
  4. 4. 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
  5. 5. 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
  6. 6. 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 = "}") }
  7. 7. LANGUAGE IDIOMS & CONCEPTS https://www.flickr.com/photos/geraldford/6976818221/
  8. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 24. KOTLIN AND ANDROID https://realm.io/assets/img/news/tutorial-kotlin-anko-cover.png
  25. 25. KOTLIN AND ANDROID TOOLCHAIN AND FLOW Java sourcesKotlin sources Bytecode javackotlinc Dalvik ART JVM
  26. 26. 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'
  27. 27. 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()
  28. 28. 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" } }
  29. 29. ANKO DSL
  30. 30. 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.
  31. 31. 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
  32. 32. 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>
  33. 33. 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)
  34. 34. ANKO DSL ANKO DSL verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } }
  35. 35. 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
  36. 36. 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"
  37. 37. 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 } } }
  38. 38. 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 }
  39. 39. 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))
  40. 40. 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)
  41. 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. 42. LIBRARIES AND TOOLS https://www.flickr.com/photos/sillygwailo/5990089210/
  43. 43. LIBRARIES AND TOOLS OVERVIEW ▸ Kotter Knife ▸ Butter Knife ▸ KAndroid ▸ Kovenant ▸ Fuel, Injekt, Spek, Kotson
  44. 44. 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)
  45. 45. 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") }
  46. 46. 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") })
  47. 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. 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. 49. LIBRARIES AND TOOLS OVERVIEW ▸ Kotter Knife ▸ Butter Knife ▸ KAndroid ▸ Kovenant ▸ Fuel, Injekt, Spek, Kotson
  50. 50. FINAL THOUGHTS https://www.flickr.com/photos/brickset/16099265973/
  51. 51. 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
  52. 52. 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
  53. 53. FINAL THOUGHTS WHAT DID WE LEARN? ▸ What is Kotlin? ▸ Language idioms & concepts ▸ Kotlin and Android ▸ Anko DSL ▸ Libraries and Tools ▸ Final thoughts
  54. 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. 55. RESOURCES GET IN TOUCH Kai Koenig Email: kai@ventego-creative.co.nz Twitter: @AgentK

×