Life is great and everything will be OK, Kotlin is here

A presentation at Google I/O in May 2017 in Mountain View, CA, USA by Jake Wharton

Slide 1

Slide 1

+Christina Lee @RunChristinaRun +Jake Wharton @JakeWharton Kotlin is here Life is great and everything will be OK

Slide 2

Slide 2

MainActivity.java public class MainActivity extends

Activity {

@Override

protected void onCreate ( Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

} 1

} 2

Slide 3

Slide 3

MainActivity.java public class MainActivity extends

Activity {

@Override

protected void onCreate ( Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

} 1

} 2

Slide 4

Slide 4

MainActivity.java public class MainActivity extends

Activity {

@Override

protected void onCreate ( Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

} 1

} 2

Slide 5

Slide 5

MainActivity.java public class MainActivity extends

Activity {

@Override

protected void onCreate (@Nullable Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

} 1

} 2

@Nullable

Slide 6

Slide 6

MainActivity.java public class MainActivity extends

Activity {

@Override

protected void onCreate (@Nullable Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

} 1

} 2

Slide 7

Slide 7

MainActivity.kt class MainActivity :

Activity () {

override fun onCreate ( savedInstanceState: Bundle ? ) {

super . onCreate ( savedInstanceState ) } 1

} 2

Slide 8

Slide 8

MainActivity.kt class MainActivity :

Activity () {

override fun onCreate ( savedInstanceState: Bundle ? ) {

super . onCreate ( savedInstanceState ) } 1

} 2

Slide 9

Slide 9

MainActivity.kt class MainActivity :

Activity () {

override fun onCreate ( savedInstanceState: Bundle ? ) {

super . onCreate ( savedInstanceState ) } 1

} 2

Slide 10

Slide 10

TextView.java public float getAlpha () {

// Retrieve value...

}

Slide 11

Slide 11

TextView.java public float getAlpha () {

// Retrieve value...

}

public void setAlpha ( float alpha ) {

// Set value...

}

Slide 12

Slide 12

TextView.java public float getAlpha () {

// Retrieve value...

}

public void setAlpha ( float alpha ) {

// Set value...

} TextView tv

// ...

Log . d ( "MainActivity" ,

"Alpha: "

tv . getAlpha ());

tv . setAlpha ( 0f ); MainActivity.java

Slide 13

Slide 13

TextView.java public float getAlpha () {

// Retrieve value...

}

public void setAlpha ( float alpha ) {

// Set value...

} MainActivity.kt val tv

// ...

Log . d ( "MainActivity" ,

"Alpha: "

tv . alpha )

tv . alpha

0f

Slide 14

Slide 14

TextView.java public float getAlpha () {

// Retrieve value...

} 1

public void setAlpha ( float alpha ) {

// Set value...

} 2

MainActivity.kt val tv

// ...

Log . d ( "MainActivity" ,

"Alpha: "

tv . alpha )

tv . alpha

0f

Slide 15

Slide 15

TextView.java public float getAlpha () {

// Retrieve value...

} 1

public void setAlpha ( float alpha ) {

// Set value...

} 2

MainActivity.kt val tv

// ...

Log . d ( "MainActivity" ,

"Alpha: "

tv . alpha )

tv . alpha

0f

Slide 16

Slide 16

TextView.java public float getAlpha () {

// Retrieve value...

} 1

public void setAlpha ( float alpha ) {

// Set value...

} 2

MainActivity.kt val tv

// ...

Log . d ( "MainActivity" ,

"Alpha: "

tv . alpha )

tv . alpha

0f

Slide 17

Slide 17

MainActivity.java LinearLayout views

= // ...

for ( int i = 0 ; i < views . getChildCount ();

i ++ ) {

View view

= views . getChildAt ( i ); // TODO do something with view

}

Slide 18

Slide 18

MainActivity.kt val views = // ... for ( index in 0 until views . childCount ) {

val view

views . getChildAt ( index )

// TODO do something with view

}

Slide 19

Slide 19

MainActivity.kt val views = // ... for ( index in 0 until views . childCount ) {

val view

views . getChildAt ( index )

// TODO do something with view

} 1

Slide 20

Slide 20

MainActivity.kt val views = // ... for ( index in 0 until views . childCount ) {

val view

views . getChildAt ( index )

// TODO do something with view

} 1

Slide 21

Slide 21

MainActivity.kt val views = // ... for ( index in 0 until views . childCount ) {

val view

views . getChildAt ( index )

// TODO do something with view

}

Slide 22

Slide 22

MainActivity.kt val views = // ... for ( index in 0 until views . childCount ) { Z

val view

views . getChildAt ( index )

// TODO do something with view

} 1 ViewGroups.kt fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3 .
Each

->

Slide 23

Slide 23

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3 val = views.getChildAt(i)

Slide 24

Slide 24

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3

Slide 25

Slide 25

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3

Slide 26

Slide 26

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3

Slide 27

Slide 27

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3

Slide 28

Slide 28

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt inline fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3 inline

Slide 29

Slide 29

MainActivity.kt val views = // ... views . forEach { Z view

->

// TODO do something with view

} 1

ViewGroups.kt inline fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3

Slide 30

Slide 30

MainActivity.kt val views = // ... views . forEach { Z view

-> /* ... */ } 1 views . forEachIndexed {

index , view

-> /* ... */ } 1

ViewGroups.kt inline fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3 inline fun ViewGroup . forEachIndexed ( action: ( Int , View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( index , getChildAt ( index )) } } // TODO do something with view

Slide 31

Slide 31

MainActivity.kt val views = // ... views . forEach { Z view

-> /* ... */ } 1 views . forEachIndexed {

index , view

-> /* ... */ } 1

ViewGroups.kt inline fun ViewGroup . forEach ( action: ( View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( getChildAt ( index )) } 2

} 3 inline fun ViewGroup . forEachIndexed ( action: ( Int , View ) -> Unit ) {

for ( index in 0 until childCount ) {

action ( index , getChildAt ( index )) } } // TODO do something with view

Slide 32

Slide 32

MainActivity.kt val views = // ... // TODO do something with view ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

Slide 33

Slide 33

MainActivity.kt val views = // ...

val first

views [ 0 ]

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index ) // TODO do something with view

Slide 34

Slide 34

MainActivity.kt val views = // ...

val first

views [ 0 ]

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index ) // TODO do something with view

Slide 35

Slide 35

MainActivity.kt val views = // ...

val first

views [ 0 ]

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index ) // TODO do something with view

Slide 36

Slide 36

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child ) // TODO do something with view

Slide 37

Slide 37

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child ) // TODO do something with view

Slide 38

Slide 38

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first views += first

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child ) // TODO do something with view

Slide 39

Slide 39

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first views += first

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child ) // TODO do something with view

Slide 40

Slide 40

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first views += first if ( first in views ) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

Slide 41

Slide 41

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first views += first if ( first in views ) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

Slide 42

Slide 42

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first views += first if ( first in views ) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

Slide 43

Slide 43

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= first views += first if ( first in views ) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

Slide 44

Slide 44

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

Slide 45

Slide 45

MainActivity.kt val views = // ...

val first

views.get ( 0 ) views . minusAssign ( first )

views . plusAssign ( first )

if ( views . contains ( first )) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

   in

Slide 46

Slide 46

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething ()

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1 // TODO do something with view

Slide 47

Slide 47

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething () Log . d ( "MainActivity" , "View count: ${ views . size } " )

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1

val ViewGroup . size : Int

get () = childCount // TODO do something with view

Slide 48

Slide 48

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething () Log . d ( "MainActivity" , "View count: ${ views . size } " )

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1

val ViewGroup . size : Int

get () = childCount // TODO do something with view

Slide 49

Slide 49

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething () Log . d ( "MainActivity" , "View count: ${ views . size } " )

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1

val ViewGroup . size : Int

get () = childCount // TODO do something with view

Slide 50

Slide 50

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething () Log . d ( "MainActivity" , "View count: ${ views . size } " )

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1

val ViewGroup . size : Int

get () = childCount // TODO do something with view

Slide 51

Slide 51

MainActivity.kt val views = // ...

val first

views [ 0 ] views -= fir st views += fi rst if ( first in views ) doSomething () Log . d ( "MainActivity" , "View count: ${ views . size } " )

ViewGroups.kt operator fun ViewGroup . get ( index: Int ) : View ?

getChildAt ( index )

operator fun ViewGroup . minusAssign ( child: View ) = removeView ( child )

operator fun ViewGroup . plusAssign ( child: View ) = addView ( child )

operator fun ViewGroup . contains ( child: View ) = indexOfChild ( child ) != - 1

val ViewGroup . size : Int

get () = childCount // TODO do something with view

Slide 52

Slide 52

MainActivity.kt val views = // ... // TODO do something with view ViewGroups.kt fun ViewGroup . children () = object : Iterable < View

{

override fun iterator () = object : Iterator < View

{

var index

= 0

override fun hasNext () = index

< childCount

override fun next () = getChildAt ( index ++) } }

Slide 53

Slide 53

MainActivity.kt val views = // ...

for ( view

in views . children ()) { // TODO do something with view

} 1

ViewGroups.kt fun ViewGroup . children () = object : Iterable < View

{

override fun iterator () = object : Iterator < View

{

var index

= 0

override fun hasNext () = index

< childCount

override fun next () = getChildAt ( index ++) } 2

} 3 // TODO do something with view

Slide 54

Slide 54

MainActivity.kt val views = // ...

for ( view

in views . children ()) { // TODO do something with view

} 1

val visibleHeight

views . children () . filter { it . visibility

View . VISIBLE

}

. sumBy { it . measuredHeight }

ViewGroups.kt fun ViewGroup . children () = object : Iterable < View

{

override fun iterator () = object : Iterator < View

{

var index

= 0

override fun hasNext () = index

< childCount

override fun next () = getChildAt ( index ++) } 2

} 3 // TODO do something with view

Slide 55

Slide 55

MainActivity.kt val views = // ...

for ( view

in views . children ()) { // TODO do something with view

}

val visibleHeight

views . children () . filter { it . visibility

View . VISIBLE

}

. sumBy { it . measuredHeight }

ViewGroups.kt fun ViewGroup . children () = object : Iterable < View

{

override fun iterator () = object : Iterator < View

{

var index

= 0

override fun hasNext () = index

< childCount

override fun next () = getChildAt ( index ++) } } // TODO do something with view

Slide 56

Slide 56

MainActivity.java Trace . beginSection ( sectionName );

expensiveCalculation ();

Trace . endSection () ;

Slide 57

Slide 57

MainActivity.java Trace . beginSection ( sectionName );

expensiveCalculation ();

Trace . endSection () ; Traces.kt inline fun

trace ( sectionName: String , body: () -> Unit )

{

Trace . beginSection ( sectionName )

try {

body () } 2 finally {

Trace . endSection () } 3

} 4

Slide 58

Slide 58

Traces.kt inline fun

trace ( sectionName: String , body: () -> Unit )

{ Z

Trace . beginSection ( sectionName )

try {

body () } 2 finally {

Trace . endSection () } 3

} 4 MainActivity.kt trace ( "foo" ) {

expensiveCalculation () } 1

Slide 59

Slide 59

Traces.kt inline fun < T

trace ( sectionName: String , body: () -> T ) :

T

{ Z

Trace . beginSection ( sectionName )

try {

return body () } 2 finally {

Trace . endSection () } 3

} 4

Unit MainActivity.kt trace ( "foo" ) {

expensiveCalculation () } 1

< T

T

T

return

Slide 60

Slide 60

Traces.kt inline fun < T

trace ( sectionName: String , body: () -> T ) :

T

{ Z

Trace . beginSection ( sectionName )

try {

return body () } 2 finally {

Trace . endSection () } 3

} 4 MainActivity.kt val result

trace ( "foo" ) {

expensiveCalculation () } 1 val result

< T

T

T

return

Slide 61

Slide 61

Traces.kt inline fun < T

trace ( sectionName: String , body: () -> T ) :

T

{ Z

Trace . beginSection ( sectionName )

try {

return body () } 2 finally {

Trace . endSection () } 3

} 4 MainActivity.kt val result

trace ( "foo" ) {

expensiveCalculation () } 1

Slide 62

Slide 62

MainActivity.java SQLiteDatabase db = // ... db . beginTransaction (); try {

db . delete ( "users" ,

"first_name = ?" ,

new

String [] { "jake" }); } finally {

db . endTransaction (); } 1

Slide 63

Slide 63

MainActivity.java SQLiteDatabase db = // ... db . beginTransaction (); try {

db . delete ( "users" ,

"first_name = ?" ,

new

String [] { "jake" });

db . setTransactionSuccessful (); } finally {

db . endTransaction (); } 1

Slide 64

Slide 64

SQLiteDatabase db = // ... db . beginTransaction (); try {

db . delete ( "users" ,

"first_name = ?" ,

new

String [] { "jake" });

db . setTransactionSuccessful (); } finally {

db . endTransaction (); } 1 Databases .kt inline fun SQLiteDatabase . transaction ( body: () -> Unit ) {

beginTransaction ()

try {

body ()

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1

Slide 65

Slide 65

MainActivity.kt val db = // ... db . transaction

{ 4

db . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: () -> Unit ) {

beginTransaction ()

try {

body () X

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1 SQLiteDatabase

db.beginTransaction(); try new String[] { } db.setTransactionSuccessful(); finally { db.endTransaction(); }1

Slide 66

Slide 66

MainActivity.kt val db = // ... db . transaction

{ 4

db . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: () -> Unit ) {

beginTransaction ()

try {

body () X

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

Slide 67

Slide 67

MainActivity.kt val db = // ... db . transaction

{ 4

db . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: () -> Unit ) {

beginTransaction ()

try {

body () X

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

Slide 68

Slide 68

MainActivity.kt val db = // ... db . transaction

{ 4

db . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: ( SQLiteDatabase ) -> Unit ) {

beginTransaction ()

try {

body () X

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

SQLiteDatabase

Slide 69

Slide 69

MainActivity.kt val db = // ... db . transaction

{ 4

db . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: ( SQLiteDatabase ) -> Unit ) {

beginTransaction ()

try {

body ( this ) X

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

SQLiteDatabase

body ( this ) X

Slide 70

Slide 70

MainActivity.kt val db = // ... db . transaction

{ 4

it . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: ( SQLiteDatabase ) -> Unit ) {

beginTransaction ()

try {

body ( this )

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

it . delete

SQLiteDatabase

body ( this ) X

Slide 71

Slide 71

MainActivity.kt val db = // ... db . transaction

{ 4

it . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: ( SQLiteDatabase ) -> Unit ) {

beginTransaction ()

try {

body ( this ) F

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

Slide 72

Slide 72

MainActivity.kt val db = // ... db . transaction

{ 4

it . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: ( SQLiteDatabase ) -> Unit ) {

beginTransaction ()

try {

body ( this ) F

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

Slide 73

Slide 73

MainActivity.kt val db = // ... db . transaction

{ 4

it . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: ( SQLiteDatabase ) -> Unit ) {

beginTransaction ()

try {

body ( this ) F

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

Slide 74

Slide 74

MainActivity.kt val db = // ... db . transaction

{ 4

it . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: SQLiteDatabase .() -> Unit ) {

beginTransaction ()

try {

body ( this ) F

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

SQLiteDatabase .() -> Unit

Slide 75

Slide 75

MainActivity.kt val db = // ... db . transaction

{ 4

it . delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: SQLiteDatabase .() -> Unit ) {

beginTransaction ()

try {

body ()

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

SQLiteDatabase .() -> Unit

body

() F

Slide 76

Slide 76

it. MainActivity.kt val db = // ... db . transaction

{ 4

delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" ) ) } 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: SQLiteDatabase .() -> Unit ) {

beginTransaction ()

try {

body ()

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1 delete

SQLiteDatabase .() -> Unit

body

() F

Slide 77

Slide 77

MainActivity.kt val db = // ... db . transaction

{ 4

delete ( "users" ,

"first_name = ?" , arrayOf ( "jake" )) G

} 3

Databases .kt inline fun SQLiteDatabase . transaction ( body: SQLiteDatabase .() -> Unit ) {

beginTransaction ()

try {

body ()

setTransactionSuccessful () } finally {

endTransaction () } 2

} 1 1

Slide 78

Slide 78

MainActivity.kt = // ... "jake" Databases.kt inline fun SQLiteDatabase.transaction(body: SQLiteDatabase.() -> Unit) { beginTransaction() try { body() setTransactionSuccessful() } finally { endTransaction() }2

}1 1 class UserPersistence ( private val db: SQLiteDatabase ) {

fun deleteByFirstName ( name: String ) {

db . transaction {

delete ( "users" , "first_name = ?" , arrayOf ( name )) G

} 3

} } UserPersistence.kt

Slide 79

Slide 79

MainActivity.kt = // ... "jake" Databases.kt inline fun SQLiteDatabase.transaction(body: SQLiteDatabase.() -> Unit) { beginTransaction() try { body() setTransactionSuccessful() } finally { endTransaction() }2

}1 1 class UserPersistence ( private val db: SQLiteDatabase ) {

fun deleteByFirstName ( name: String ) {

db . transaction {

delete ( "users" , "first_name = ?" , arrayOf ( name )) G

} 3

} } UserPersistence.kt

Slide 80

Slide 80

class UserPersistence ( private val db: SQLiteDatabase ) {

fun deleteByFirstName ( name: String ) {

db . transaction {

delete ( "users" , "first_name = ?" , arrayOf ( name )) G

} 3

} 2

} 1 UserPersistence.kt

Slide 81

Slide 81

class UserPersistence ( private val db: SQLiteDatabase ) {

private val

deleteByFirstName

db . compileStatement (

"DELETE FROM users WHERE first_name = ?" )

fun deleteByFirstName ( name: String ) {

db . transaction {

deleteByFirstName . bindString ( 1 , name )

deleteByFirstName . execute ()

} 3

} 2

} 1 UserPersistence.kt

delete(" ", " , arrayOf ( ))G

Slide 82

Slide 82

sssssssssssss class UserPersistence ( private val db: SQLiteDatabase ) {

private val

deleteByFirstName

db . compileStatement (

"DELETE FROM users WHERE first_name = ?" )

fun deleteByFirstName ( name: String ) {

db . transaction {

deleteByFirstName . bindString ( 1 , name )

deleteByFirstName . execute ()

} 3

} 2

} 1 UserPersistence.kt

Slide 83

Slide 83

sssssssssssss class UserPersistence ( private val db: SQLiteDatabase ) {

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) }

fun deleteByFirstName ( name: String ) {

db . transaction {

deleteByFirstName . bindString ( 1 , name )

deleteByFirstName . execute ()

} 3

} 2

} 1 UserPersistence.kt

Slide 84

Slide 84

sssssssssssss class UserPersistence ( private val db: SQLiteDatabase ) {

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) } X

fun deleteByFirstName ( name: String ) {

db . transaction {

deleteByFirstName . bindString ( 1 , name )

deleteByFirstName . execute ()

} 3

} 2

} 1 UserPersistence.kt

Slide 85

Slide 85

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) } X

Slide 86

Slide 86

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) } X private val name

by Delegates . observable ( "jane" ) { old , new , prop ->

println ( "Name changed from $ old to $ new " ) }

Slide 87

Slide 87

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) } X private val name

by Delegates . observable ( "jane" ) { old , new , prop ->

println ( "Name changed from $ old to $ new " ) }

private val address

by Delegates . notNull < String

()

Slide 88

Slide 88

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) } X private val name

by Delegates . observable ( "jane" ) { old , new , prop ->

println ( "Name changed from $ old to $ new " ) }

private val address

by Delegates . notNull < String

()

private val nameView

by bindView < TextView

( R . id . name )

Slide 89

Slide 89

private val deleteByFirstName

by lazy {

db . compileStatement ( "DELETE FROM users WHERE first_name = ?" ) } X private val name

by Delegates . observable ( "jane" ) { old , new , prop ->

println ( "Name changed from $ old to $ new " ) }

private val address

by Delegates . notNull < String

()

private val nameView

by bindView < TextView

( R . id . name )

Slide 90

Slide 90

class MyListener : TransitionListener {

override fun onTransitionEnd ( transition: Transition ) { }

override fun onTransitionResume ( transition: Transition ) { }

override fun onTransitionPause ( transition: Transition ) { }

override fun onTransitionCancel ( transition: Transition ) { }

override fun onTransitionStart ( transition: Transition ) { } Y

} X

Slide 91

Slide 91

class MyListener : TransitionListener {

override fun onTransitionStart ( transition: Transition ) { } Y

} X

Slide 92

Slide 92

class MyListener : TransitionListener {

override fun onTransitionStart ( transition: Transition ) { } Y

} X

object EmptyTransitionListener : TransitionListener {

override fun onTransitionEnd ( transition: Transition ) {}

override fun onTransitionResume ( transition: Transition ) {}

override fun onTransitionPause ( transition: Transition ) {}

override fun onTransitionCancel ( transition: Transition ) {}

override fun onTransitionStart ( transition: Transition ) {} }

Slide 93

Slide 93

class MyListener : TransitionListener {

override fun onTransitionStart ( transition: Transition ) { } Y

} X

object EmptyTransitionListener : TransitionListener {

override fun onTransitionEnd ( transition: Transition ) {}

override fun onTransitionResume ( transition: Transition ) {}

override fun onTransitionPause ( transition: Transition ) {}

override fun onTransitionCancel ( transition: Transition ) {}

override fun onTransitionStart ( transition: Transition ) {} }

Slide 94

Slide 94

class MyListener : TransitionListener { T

override fun onTransitionStart ( transition: Transition ) { } Y

} X

object EmptyTransitionListener : TransitionListener {

override fun onTransitionEnd ( transition: Transition ) {}

override fun onTransitionResume ( transition: Transition ) {}

override fun onTransitionPause ( transition: Transition ) {}

override fun onTransitionCancel ( transition: Transition ) {}

override fun onTransitionStart ( transition: Transition ) {} } G

Slide 95

Slide 95

class MyListener : TransitionListener by EmptyTransitionListener { T

override fun onTransitionStart ( transition: Transition ) { } Y

} X

object EmptyTransitionListener : TransitionListener {

override fun onTransitionEnd ( transition: Transition ) {}

override fun onTransitionResume ( transition: Transition ) {}

override fun onTransitionPause ( transition: Transition ) {}

override fun onTransitionCancel ( transition: Transition ) {}

override fun onTransitionStart ( transition: Transition ) {} } G

Slide 96

Slide 96

class MyListener : TransitionListener by EmptyTransitionListener { T

override fun onTransitionStart ( transition: Transition ) { } Y

} X

object EmptyTransitionListener : TransitionListener {

override fun onTransitionEnd ( transition: Transition ) {}

override fun onTransitionResume ( transition: Transition ) {}

override fun onTransitionPause ( transition: Transition ) {}

override fun onTransitionCancel ( transition: Transition ) {}

override fun onTransitionStart ( transition: Transition ) {} } G

Slide 97

Slide 97

class PaymentRobot {

fun amount ( value: Long ) { // TODO Espresso interactions

}

fun recipient ( value: String ) { // TODO Espresso interactions

}

fun send () { // TODO Espresso interactions

} } PaymentRobot.kt

Slide 98

Slide 98

@Test

fun sendMoney () {

PaymentRobot (). apply {

amount ( 4_00 )

recipient ( "foo@example.com" )

send ()

} } PaymentTest.kt

Slide 99

Slide 99

class PaymentRobot {

fun amount ( value: Long ) { // TODO Espresso interactions

}

fun recipient ( value: String ) { // TODO Espresso interactions

}

fun send () { // TODO Espresso interactions

} }

PaymentRobot.kt

Slide 100

Slide 100

class PaymentRobot {

fun amount ( value: Long ) { // TODO Espresso interactions

}

fun recipient ( value: String ) { // TODO Espresso interactions

}

fun send () { // TODO Espresso interactions

} }

PaymentRobot.kt fun payment ( body: PaymentRobot .() -> Unit ) = PaymentRobot (). apply ( body )

Slide 101

Slide 101

class PaymentRobot {

fun amount ( value: Long ) { // TODO Espresso interactions

}

fun recipient ( value: String ) { // TODO Espresso interactions

}

fun send () { // TODO Espresso interactions

} }

PaymentRobot.kt fun payment ( body: PaymentRobot .() -> Unit ) = PaymentRobot (). apply ( body )

Slide 102

Slide 102

@Test

fun sendMoney () {

PaymentRobot (). apply { T

amount ( 4_00 )

recipient ( "foo@example.com" )

send ()

} T

} G

PaymentTest.kt

p

Slide 103

Slide 103

@Test

fun sendMoney () {

payment { T

amount ( 4_00 )

recipient ( "foo@example.com" )

send ()

} T

} G

PaymentTest.kt

Slide 104

Slide 104

sealed class Payloads { } G

Slide 105

Slide 105

sealed class Payloads {

data class Favorite ( val favorited: Boolean ) : Payloads () } G

Slide 106

Slide 106

sealed class Payloads {

data class Favorite ( val favorited: Boolean ) : Payloads ()

data class Retweet ( val retweeted: Boolean ) : Payloads () } G

Slide 107

Slide 107

sealed class Payloads {

data class Favorite ( val favorited: Boolean ) : Payloads ()

data class Retweet ( val retweeted: Boolean ) : Payloads ()

data class CountUpdate (

val favorites: Long ,

val retweets: Long ,

val replies: Long ) : Payloads () } G

Slide 108

Slide 108

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

} 1

Slide 109

Slide 109

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

} 2

} 1

Slide 110

Slide 110

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

}

3

} 2

} 1

Slide 111

Slide 111

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

is Favorite -> holder . favoriteIcon . isActivated

= it . favorited

}

3

} 2

} 1

Slide 112

Slide 112

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

is Favorite -> holder . favoriteIcon . isActivated

= it . favorited

}

3

} 2

} 1

Slide 113

Slide 113

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

is Favorite -> holder . favoriteIcon . isActivated

= it . favorited

}

3

} 2

} 1 sealed class Payloads {

data class Favorite ( val favorited: Boolean ) : Payloads ()

data class Retweet ( val retweeted: Boolean ) : Payloads ()

data class CountUpdate (

val favorites: Long ,

val retweets: Long ,

val replies: Long ) : Payloads () } G

Slide 114

Slide 114

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

is Favorite -> holder . favoriteIcon . isActivated

= it . favorited

}

3

} 2

} 1

Slide 115

Slide 115

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

is Favorite -> holder . favoriteIcon . isActivated

= it . favorited

is Retweet -> holder . retweetIcon . isActivated

= it . retweeted

}

3

} 2

} 1

Slide 116

Slide 116

override fun onBindViewHolder ( holder: TweetViewHolder ,

position: Int , payloads: List < Any

) {

payloads . forEach {

when ( it ) {

is Favorite -> holder . favoriteIcon . isActivated

= it . favorited

is Retweet -> holder . retweetIcon . isActivated

= it . retweeted

is CountUpdate -> {

holder . apply {

favoriteCount . text

= it . favorites . toString ()

retweetCount . text

= it . retweets . toString ()

replyCount . text

= it . replies . toString ()

} 5

} 4

}

3

} 2

} 1

Slide 117

Slide 117

Slide 118

Slide 118

It takes great salesmanship to convince a customer to buy something from you that isn't built or isn't finished.

   Fred Wilson

Slide 119

Slide 119

Slide 120

Slide 120

Slide 121

Slide 121

Step 3 Step 2 Step 1

Slide 122

Slide 122

Step 1 Step 3 You Step 2

Slide 123

Slide 123

Step 3 Management Step 2 Step 1

Slide 124

Slide 124

Team Step 3 Step 2 Step 1

Slide 125

Slide 125

You Get excited.

Slide 126

Slide 126

Never doubt that a small group of thoughtful, committed citizens can change the world; indeed, 
 it's the only thing 
 that ever has.

Margaret Mead (Def. not talking about tech)

Slide 127

Slide 127

Be enthusiastic

Slide 128

Slide 128

Adoption is work. If you want it, you need to earn it.

Slide 129

Slide 129

Management Be persuasive.

Slide 130

Slide 130

I call it my billion- dollar mistake . Sir Charles Antony Richard Hoare

Slide 131

Slide 131

One of the most feared expressions in modern times is 'The computer is down.'

Norman Ralph Augustine

Slide 132

Slide 132

Slide 133

Slide 133

Jake Wharton

@JakeWharton Ty p e s y s t e m s a r e a f o r m o f t e s t s . I d e c l a r e a n e x p e c t e d
type and the tests (aka compiler) validates the actual ones. 6:43 PM - 11 Jan 2017 74 Follow 16

Slide 134

Slide 134

Slide 135

Slide 135

Team Do the work.

Slide 136

Slide 136

Ellen Shapiro

@designatednerd My style: “I’m the idiot who went down the rabbit hole first, and I’m here to tell you which path leads to fluffy bunnies vs. angry moles.” 14 Mar Ellen Shapiro

@designatednerd My favorite bit of any talk I give is talking about the dumb shit I did so the audience doesn’t do it. Makes the hair pulled out worth it. 4:56 PM - 14 Mar 2017 1 Follow

Slide 137

Slide 137

Define success

Slide 138

Slide 138

Slide 139

Slide 139

Slide 140

Slide 140

http://blog.danlew.net/

Slide 141

Slide 141

On-boarding should be a first class citizen

Slide 142

Slide 142

Show up

Slide 143

Slide 143

Slide 144

Slide 144

What’s next? Kotlin documentation and koans

https://kotlinlang.org/

Android Kotlin documentation

https://developer.android.com/kotlin/index.html

Kotlin In Action

Dimitry Jemerov, Svetlana Isakova

Slide 145

Slide 145

+Christina Lee @RunChristinaRun #KotlinIsHere Thank you!

+Jake Wharton @JakeWharton

Slide 146

Slide 146