Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Development with Kotlin (AndroidKW #001)

Android Development with Kotlin (AndroidKW #001)

Using Kotlin for Android development has grown in popularity over the last year. Even to those who are not currently using it, the value proposition of the language immediately resonates. There already are a lot of introductory talks to the language and its extensions for use on Android. This talk will cover advancing the usage and design patterns of the language for Android development to solve larger problems. While the content is targeted at mobile development, there will be value for all Java developers interested in Kotlin.

Prior knowledge or use of Kotlin is not required to attend this talk. Some concepts of the language will be used without introduction but they are intuitive and/or quickly learned. Even if you don't fully understand every language concept on which each example is built, the resulting functionality will be clear.

Presented at http://www.meetup.com/androidkw/events/226683586/

Video: http://youtu.be/A2LukgT2mKc

Jake Wharton
PRO

December 03, 2015
Tweet

More Decks by Jake Wharton

Other Decks in Programming

Transcript

  1. Jake Wharton
    Android Development
    with Kotlin

    View Slide

  2. Why do we need Kotlin?

    View Slide

  3. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish

    View Slide

  4. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time

    View Slide

  5. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time
    • No streams

    View Slide

  6. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time
    • No streams
    • No lambdas, method refs, non-capturing anon class

    View Slide

  7. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time
    • No streams
    • No lambdas, method refs, non-capturing anon class
    • No try-with-resources

    View Slide

  8. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time Use ThreeTenBP / ThreeTenABP
    • No streams
    • No lambdas, method refs, non-capturing anon class
    • No try-with-resources

    View Slide

  9. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time Use ThreeTenBP / ThreeTenABP
    • No streams Use backport or RxJava
    • No lambdas, method refs, non-capturing anon class
    • No try-with-resources

    View Slide

  10. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time Use ThreeTenBP / ThreeTenABP
    • No streams Use backport or RxJava
    • No lambdas, method refs, non-capturing anon class Use Retrolambda
    • No try-with-resources

    View Slide

  11. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • No javax.time Use ThreeTenBP / ThreeTenABP
    • No streams Use backport or RxJava
    • No lambdas, method refs, non-capturing anon class Use Retrolambda
    • No try-with-resources minSdkVersion=19 or Retrolambda

    View Slide

  12. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • Java language restrictions and problems

    View Slide

  13. Why do we need Kotlin?
    • Java language restrictions and problems

    View Slide

  14. Why do we need Kotlin?
    • Java language restrictions and problems
    • Inability to add methods to platform types

    View Slide

  15. Why do we need Kotlin?
    • Java language restrictions and problems
    • Inability to add methods to platform types ("Util" hell)

    View Slide

  16. Why do we need Kotlin?
    • Java language restrictions and problems
    • Inability to add methods to platform types ("Util" hell)
    • Nullability problems

    View Slide

  17. Why do we need Kotlin?
    • Java language restrictions and problems
    • Inability to add methods to platform types ("Util" hell)
    • Nullability problems
    • Mutability problems

    View Slide

  18. Why do we need Kotlin?
    • Java language restrictions and problems
    • Inability to add methods to platform types ("Util" hell)
    • Nullability problems
    • Mutability problems
    • General verbosity of common idioms

    View Slide

  19. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • Java language restrictions and problems
    • Android API design problems

    View Slide

  20. Why do we need Kotlin?
    • Android API design problems

    View Slide

  21. Why do we need Kotlin?
    • Android API design problems
    • Inheritance party

    View Slide

  22. Why do we need Kotlin?
    • Android API design problems
    • Inheritance party
    • Nullability everywhere

    View Slide

  23. Why do we need Kotlin?
    • Android API design problems
    • Inheritance party
    • Nullability everywhere
    • Ceremony of APIs

    View Slide

  24. Why do we need Kotlin?
    • Stuck on Java 6(.5)ish
    • Java language restrictions and problems
    • Android API design problems

    View Slide

  25. Kotlin
    Statically typed programming language
    for the JVM, Android, and the browser
    100% interoperable with Java™

    View Slide

  26. Syntax Crash Course

    View Slide

  27. Syntax Crash Course
    fun sum(a: Int, b: Int): Int {

    return a + b

    }

    View Slide

  28. Syntax Crash Course
    fun sum(a: Int, b: Int): Int {

    return a + b

    }X

    View Slide

  29. Syntax Crash Course
    fun sum(a: Int, b: Int): Int {

    return a + b

    }X

    View Slide

  30. Syntax Crash Course
    fun sum(a: Int, b: Int): Int {

    return a + b

    }X

    View Slide

  31. Syntax Crash Course
    fun sum(a: Int, b: Int) = a + b

    View Slide

  32. Syntax Crash Course
    fun main(args: Array) {

    println("Args: $args")

    }

    View Slide

  33. Syntax Crash Course
    fun main(args: Array) {

    println("Args: $args")

    }X

    View Slide

  34. Syntax Crash Course
    fun main(args: Array) {

    println("Args: $args")

    }X

    View Slide

  35. Syntax Crash Course
    fun main(args: Array) {

    println("Args: $args")

    }X

    View Slide

  36. Syntax Crash Course
    val name = "Jake"

    val people: List = ArrayList()

    View Slide

  37. Syntax Crash Course
    val name = "Jake"

    val people: List = ArrayList()

    View Slide

  38. Syntax Crash Course
    val name = "Jake"

    val people: List = ArrayList()

    View Slide

  39. Syntax Crash Course
    val name = "Jake"

    val people: List = ArrayList()

    View Slide

  40. Syntax Crash Course
    val name = "Jake"

    val people: List = ArrayList()

    View Slide

  41. Extension Functions

    View Slide

  42. Extension Functions
    static boolean isTuesday(Date date) {

    return date.getDay() == 2;

    }

    View Slide

  43. Extension Functions
    static boolean isTuesday(Date date) {

    return date.getDay() == 2;

    }
    boolean tuesday = DateUtils.isTuesday(date);

    View Slide

  44. Extension Functions
    fun Date.isTuesday(): Boolean {

    return getDay() == 2

    }X

    View Slide

  45. Extension Functions
    fun Date.isTuesday(): Boolean {

    return getDay() == 2

    }X

    View Slide

  46. Extension Functions
    fun Date.isTuesday(): Boolean {

    return getDay() == 2

    }X

    View Slide

  47. Extension Functions
    fun Date.isTuesday(): Boolean {

    return getDay() == 2

    }X
    val tuesday = date.isTuesday()

    View Slide

  48. Extension Functions
    fun Date.isTuesday(): Boolean {

    return day == 2

    }X
    val tuesday = date.isTuesday()

    View Slide

  49. Extension Functions
    fun Date.isTuesday() = day == 2
    val tuesday = date.isTuesday()

    View Slide

  50. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    // com/example/TuesdayActivity.kt
    val tuesday = date.isTuesday()

    View Slide

  51. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    // com/example/TuesdayActivity.kt
    val tuesday = date.isTuesday()

    View Slide

  52. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    // com/example/TuesdayActivity.kt
    import com.example.util.isTuesday
    val tuesday = date.isTuesday()

    View Slide

  53. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    final static isTuesday(Ljava/util/Date;)Z
    L0
    ALOAD 0
    INVOKEVIRTUAL java/util/Date.getDay ()I
    ICONST_2
    IF_ICMPNE L1
    ICONST_1
    GOTO L2
    L1
    ICONST_0
    L2
    IRETURN

    View Slide

  54. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    static boolean isTuesday(Date date) {

    return date.getDay() == 2;

    }X

    View Slide

  55. Extension Functions
    // com/example/util/DateExtensions.kt
    // com/example/util/DateExtensionsKt.java
    fun Date.isTuesday() = day == 2
    static boolean isTuesday(Date date) {

    return date.getDay() == 2;

    }X

    View Slide

  56. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    @file:JvmName("DateUtils")
    // com/example/util/DateExtensionsKt.java
    static boolean isTuesday(Date date) {

    return date.getDay() == 2;

    }X

    View Slide

  57. Extension Functions
    // com/example/util/DateExtensions.kt
    fun Date.isTuesday() = day == 2
    @file:JvmName("DateUtils")
    // com/example/util/DateUtils.java
    static boolean isTuesday(Date date) {

    return date.getDay() == 2;

    }X

    View Slide

  58. Extension Functions
    fun Date.getDay() = 2

    View Slide

  59. Extension Functions
    fun Date.getDay() = 2

    View Slide

  60. Extension Functions
    fun Date.getDay() = 2
    fun View.isAttachedToWindow() =
    if (Build.VERSION.SDK_INT < 19)
    ViewCompat.isAttachedToWindow(this)
    else
    super.isAttachedToWindow()

    View Slide

  61. Extension Functions
    fun Date.getDay() = 2
    fun View.isAttachedToWindowCompat() =
    if (Build.VERSION.SDK_INT < 19)
    ViewCompat.isAttachedToWindow(this)
    else
    isAttachedToWindow()

    View Slide

  62. Extension Functions
    String firstName1=2cursor.getString(
    cursor.getColumnIndexOrThrow("first_name"));

    View Slide

  63. Extension Functions
    String firstName1= null;

    int firstNameColumn = cursor.getColumnIndexOrThrow("first_name");

    if (!cursor.isNull(firstNameColumn)) {

    firstName3=2cursor.getString(firstNameColumn);

    }

    View Slide

  64. Extension Functions
    String firstName1= null;

    int firstNameColumn = cursor.getColumnIndexOrThrow("first_name");

    if (!cursor.isNull(firstNameColumn)) {

    firstName3=2cursor.getString(firstNameColumn);

    }
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!

    View Slide

  65. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!

    View Slide

  66. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName = cursor.getStringOrNull("first_name")

    View Slide

  67. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName = cursor.getStringOrNull("first_name")

    View Slide

  68. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String? = cursor.getStringOrNull("first_name")

    View Slide

  69. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String? = cursor.getStringOrNull("first_name")
    if (firstName != null) {
    firstNameView.setText(firstName)
    }X

    View Slide

  70. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String? = cursor.getStringOrNull("first_name")
    if (firstName != null) {
    firstNameView.setText(firstName) // firstName not String?, now String
    }X

    View Slide

  71. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String? = cursor.getStringOrNull("first_name")
    firstNameView.setText(firstName ?: "Jake")

    View Slide

  72. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName = cursor.getString("first_name")

    View Slide

  73. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String = cursor.getString("first_name")

    View Slide

  74. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String = cursor.getString("first_name")
    firstNameView.setText(firstName)

    View Slide

  75. Extension Functions
    fun Cursor.getStringOrNull(columnName: String): String? {

    val index = getColumnIndexOrThrow(columnName)

    return if (isNull(index)) null else getString(index)

    }X

    fun Cursor.getString(columnName: String): String =
    getStringOrNull(columnName)!!
    val firstName: String = cursor.getString("first_name")
    firstNameView.setText(firstName)

    View Slide

  76. Function Expressions

    View Slide

  77. Function Expressions
    { it.toString() }

    View Slide

  78. Function Expressions
    { x, y -> x + y }
    { it.toString() }

    View Slide

  79. Function Expressions
    { x, y -> x + y }
    { x: Int, y: Int -> x + y }
    { it.toString() }
    { x, y -> x + y }
    { x: Int, y: Int -> x + y }

    View Slide

  80. Function Expressions
    { x, y -> x + y }
    { x: Int, y: Int -> x + y }
    val sum = { x: Int, y: Int -> x + y }
    val sum: (Int, Int) -> Int = { x, y -> x + y }
    { it.toString() }

    View Slide

  81. Function Expressions
    { x, y -> x + y }
    { x: Int, y: Int -> x + y }
    val sum = { x: Int, y: Int -> x + y }
    val sum: (Int, Int) -> Int = { x, y -> x + y }
    { it.toString() }

    View Slide

  82. Function Expressions
    { x, y -> x + y }
    { x: Int, y: Int -> x + y }
    val sum = { x: Int, y: Int -> x + y }
    val sum: (Int, Int) -> Int = { x, y -> x + y }
    { it.toString() }

    View Slide

  83. Function Expressions
    { !it.isEmpty() }
    { it.length() > 4 }
    { it.matches("\\d{4}") }
    { luhnCheck(it) }

    View Slide

  84. Function Expressions
    val notEmpty: (String) -> Boolean = { !it.isEmpty() }
    val atLeastFour: (String) -> Boolean = { it.length() > 4 }
    val fourDigits: (String) -> Boolean = { it.matches("\\d{4}") }
    val validCreditCard: (String) -> Boolean = { luhnCheck(it) }

    View Slide

  85. Higher-Order Functions

    View Slide

  86. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {
    // ...

    }X

    View Slide

  87. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {
    // ...

    }X

    View Slide

  88. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {
    // ...

    }X

    View Slide

  89. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {
    // ...

    }X

    View Slide

  90. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {

    val newList = ArrayList()
    // ...

    return newList

    }X

    View Slide

  91. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {

    val newList = ArrayList()

    for (item in this) {
    // ...

    }Y

    return newList

    }X

    View Slide

  92. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {

    val newList = ArrayList()

    for (item in this) {

    if (predicate(item)) {
    // ...

    }Z

    }Y

    return newList

    }X

    View Slide

  93. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {

    val newList = ArrayList()

    for (item in this) {

    if (predicate(item)) {

    newList.add(item)

    }Z

    }Y

    return newList

    }X

    View Slide

  94. Higher-Order Functions
    fun List.filter(predicate: (T) -> Boolean): List {

    val newList = ArrayList()

    for (item in this) {

    if (predicate(item)) {

    newList.add(item)

    }

    }

    return newList

    }
    val names = listOf("Jake", "Jesse", "Matt", "Alec")

    val jakes = names.filter { it == "Jake" }


    View Slide

  95. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }X

    }X

    }X

    View Slide

  96. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }X

    }X

    }X

    View Slide

  97. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }X

    }X

    }X

    View Slide

  98. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }X

    }X

    }X

    View Slide

  99. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }

    }

    }

    View Slide

  100. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }

    }

    }
    val readerLock = Lock(JsonReader(stream))

    View Slide

  101. Higher-Order Functions
    data class Lock(private val obj: T) {

    public fun acquire(func: (T) -> Unit) {

    synchronized (obj) {

    func(obj)

    }

    }

    }
    val readerLock = Lock(JsonReader(stream))


    // Later

    readerLock.acquire { 

    println(it.readString())

    }

    View Slide

  102. Higher-Order Functions
    val notEmpty: (String) -> Boolean = { !it.isEmpty() }
    val atLeastFour: (String) -> Boolean = { it.length() > 4 }
    val fourDigits: (String) -> Boolean = { it.matches("\\d{4}") }
    val validCreditCard: (String) -> Boolean = { luhnCheck(it) }

    View Slide

  103. Higher-Order Functions
    val notEmpty: (String) -> Boolean = { !it.isEmpty() }
    val atLeastFour: (String) -> Boolean = { it.length() > 4 }
    val fourDigits: (String) -> Boolean = { it.matches("\\d{4}") }
    val validCreditCard: (String) -> Boolean = { luhnCheck(it) }
    firstName.validateWith(notEmpty)
    lastName.validateWith(notEmpty)
    username.validateWith(atLeastFour)
    pin.validateWith(fourDigits)
    creditCard.validateWith(validCreditCard)
    { !it.isEmpty() }

    View Slide

  104. Higher-Order Functions
    firstName.validateWith { !it.isEmpty() }
    lastName.validateWith { !it.isEmpty() }
    username.validateWith { it.length() > 4 }
    pin.validateWith { it.matches("\\d{4}") }
    creditCard.validateWith { luhnCheck(it) }

    View Slide

  105. Higher-Order Functions
    val notEmpty: (String) -> Boolean = { !it.isEmpty() }
    firstName.validateWith(notEmpty)
    lastName.validateWith(notEmpty)
    username.validateWith { it.length() > 4 }
    pin.validateWith { it.matches("\\d{4}") }
    creditCard.validateWith { luhnCheck(it) }
    { !it.isEmpty() }

    View Slide

  106. Extension Function Expressions

    View Slide

  107. Extension Function Expressions
    • Extension Functions — Functions added to a type without modifying
    the original.

    View Slide

  108. Extension Function Expressions
    • Extension Functions — Functions added to a type without modifying
    the original.
    • Function Expressions — Undeclared function bodies used an as
    expression (i.e., as data).

    View Slide

  109. Extension Function Expressions
    • Extension Functions — Functions added to a type without modifying
    the original.
    • Function Expressions — Undeclared function bodies used an as
    expression (i.e., as data).
    • Higher-Order Functions: A function which takes a function or returns
    a function.

    View Slide

  110. Extension Function Expressions
    db.beginTransaction();

    try {

    db.delete("users", "first_name = ?", new String[] { "Jake" });

    } finally {

    db.endTransaction();

    }X

    View Slide

  111. Extension Function Expressions
    db.beginTransaction();

    try {

    db.delete("users", "first_name = ?", new String[] { "Jake" });

    db.setTransactionSuccessful();

    } finally {

    db.endTransaction();

    }X

    View Slide

  112. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: () -> Unit) {

    beginTransaction()

    try {

    func()

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }

    }

    View Slide

  113. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: () -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    }X
    )

    View Slide

  114. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: () -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    db.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  115. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: () -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    db.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  116. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    db.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  117. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    db.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  118. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    db.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  119. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    db.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  120. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  121. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  122. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: (SQLiteDatabase) -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  123. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  124. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func(this

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  125. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    this.func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  126. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  127. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func(

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    it.delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    )

    View Slide

  128. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func()

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    delete("users", "first_name = ?", arrayOf("Jake"))

    }X

    View Slide

  129. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func()

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X
    db.inTransaction { 

    delete("users", "first_name = ?", arrayOf("Jake"))

    }X

    View Slide

  130. Extension Function Expressions
    db.inTransaction { 

    delete("users", "first_name = ?", arrayOf("Jake"))

    }X

    View Slide

  131. Extension Function Expressions
    NEW MyClassKt$deleteUsers$1
    DUP
    ALOAD 2
    INVOKESPECIAL MyClassKt$deleteUsers$1. (Ljava/lang/String;)V
    CHECKCAST kotlin/jvm/functions/Function1
    INVOKESTATIC DbExtensionsKt.inTransaction
    (Landroid/database/sqlite/SQLiteDatabase;Lkotlin/jvm/functions/Function1;)V
    db.inTransaction { 

    delete("users", "first_name = ?", arrayOf("Jake"))

    }X

    View Slide

  132. Extension Function Expressions
    DbExtensions.inTransaction(db, new Function1() {

    @Override public Unit invoke(SQLiteDatabase db) {

    db.delete("users", "first_name = ?", new String[] { "Jake "});

    return null;

    }

    });
    db.inTransaction { 

    delete("users", "first_name = ?", arrayOf("Jake"))

    }X

    View Slide

  133. Extension Function Expressions
    fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func()

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X

    View Slide

  134. Extension Function Expressions
    inline fun SQLiteDatabase.inTransaction(func: SQLiteDatabase.() -> Unit) {

    beginTransaction()

    try {

    func()

    setTransactionSuccessful()

    } finally {

    endTransaction()

    }Y

    }X

    View Slide

  135. Extension Function Expressions
    L6
    ALOAD 2
    INVOKEVIRTUAL com/example/SQLiteDatabase.beginTransaction ()V
    L0
    NOP
    L9
    ALOAD 2
    CHECKCAST com/example/SQLiteDatabase
    ASTORE 3
    L10
    ALOAD 3
    LDC "users"
    LDC "first_name = ?"
    ICONST_1
    ANEWARRAY java/lang/String
    DUP
    ICONST_0
    LDC "Jake"
    AASTORE
    CHECKCAST [Ljava/lang/String;
    INVOKEVIRTUAL com/example/SQLiteDatabase.delete (Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
    L11
    L12
    GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
    POP
    L13
    ALOAD 2
    INVOKEVIRTUAL com/example/SQLiteDatabase.setTransactionSuccessful ()V
    L1
    ALOAD 2
    INVOKEVIRTUAL com/example/SQLiteDatabase.endTransaction ()V
    L14
    GOTO L15
    L2
    ASTORE 3
    L3
    ALOAD 2
    INVOKEVIRTUAL com/example/SQLiteDatabase.endTransaction ()V

    View Slide

  136. Extension Function Expressions
    db.beginTransaction();

    try {

    db.delete("users", "first_name = ?", new String[] { "Jake "});

    db.setTransactionSuccessful();

    } finally {

    db.endTransaction();

    }X

    View Slide

  137. Extension Function Expressions
    db.beginTransaction();

    try {

    db.delete("users", "first_name = ?", new String[] { "Jake "});

    db.setTransactionSuccessful();

    } finally {

    db.endTransaction();

    }X
    db.inTransaction { 

    delete("users", "first_name = ?", arrayOf("Jake"))

    }X
    +
    inline fun
    =

    View Slide

  138. Extension Function Expressions
    inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {

    val editor = edit()

    editor.func()

    editor.apply()

    }

    View Slide

  139. Extension Function Expressions
    inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {

    val editor = edit()

    editor.func()

    editor.apply()

    }X
    preferences.edit { 

    putString("foo", "bar")

    putString("fizz", "buzz")

    remove("username")

    }X

    View Slide

  140. Extension Function Expressions
    inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {

    val editor = edit()

    editor.func()

    editor.apply()

    }X

    fun SharedPreferences.Editor.set(pair: Pair) =

    putString(pair.first, pair.second)
    preferences.edit { 

    putString("foo", "bar")

    putString("fizz", "buzz")

    remove("username")

    }X

    View Slide

  141. Extension Function Expressions
    inline fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {

    val editor = edit()

    editor.func()

    editor.apply()

    }X

    fun SharedPreferences.Editor.set(pair: Pair) =

    putString(pair.first, pair.second)
    preferences.edit {

    set("foo" to "bar")

    set("fizz" to "buzz")

    remove("username")

    }X







    putString

    putString

    View Slide

  142. Extension Function Expressions
    inline fun notification(context: Context,
    func: Notification.Builder.() -> Unit): Notification {

    val builder = Notification.Builder(context)

    builder.func()

    return builder.build()

    }

    View Slide

  143. Extension Function Expressions
    inline fun notification(context: Context,
    func: Notification.Builder.() -> Unit): Notification {

    val builder = Notification.Builder(context)

    builder.func()

    return builder.build()

    }
    val n = notification(context) {

    setContentTitle("Hi")

    setSubText("Hello")

    }

    View Slide

  144. Extension Function Expressions
    verticalLayout {

    padding = dip(30)

    editText {

    hint = "Name"

    textSize = 24f

    }

    editText {

    hint = "Password"

    textSize = 24f

    }

    button("Login") {

    textSize = 26f

    }

    }

    View Slide

  145. Resources

    View Slide

  146. Resources
    • Website and documentation

    https://kotlinlang.org/

    View Slide

  147. Resources
    • Website and documentation

    https://kotlinlang.org/
    • Online IDE

    http://try.kotlinlang.org/

    View Slide

  148. Resources
    • Website and documentation

    https://kotlinlang.org/
    • Online IDE

    http://try.kotlinlang.org/
    • Kotlin Koans

    http://try.kotlinlang.org/koans

    View Slide

  149. jakewharton
    jakewharton
    jakewharton
    twitter.com/
    google.com/+
    .com
    Android Development
    with Kotlin

    View Slide