@kropp rome - april 13/14 2018 kotlin for android developers for android developers.pdf · kotlin...

62
Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018

Upload: others

Post on 22-May-2020

20 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Kotlin for Android developersVictor Kropp, JetBrains@kropp

ROME - APRIL 13/14 2018

Page 2: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin
Page 3: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Kotlin on

JVM + AndroidJS

In development: Kotlin/NativeiOS/macOS/Windows/Linux

Page 4: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Links

Kotlinhttps://kotlinlang.orgKotlin Koanshttps://try.kotl.in

Kotlin in Action bookby Dmitry Jemerov & Svetlana Isakova

Page 5: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Sample Java App

package kropp.name.myapp;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

Page 6: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

Page 7: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

Page 8: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 9: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 10: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 11: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 12: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 13: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity {

override fun onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 14: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity {

override fun onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 15: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity {

override fun onCreate(savedInstanceState: Bundle) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 16: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Converting to Kotlin

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 17: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Sample Kotlin App

package kropp.name.myapp

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

}

Page 18: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Data classes

data class Person( var firstName: String, var lastName: String, var age: Int

)

Page 19: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Java equivalent

package kotlindemo;

import java.util.Objects;

public class Person { private String firstName; private String lastName; private int age;

public Person(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; }

public String getFirstName() { return firstName; }

public void setFirstName(String firstName) { this.firstName = firstName; }

public String getLastName() { return lastName; }

public void setLastName(String lastName) { this.lastName = lastName; }

public int getAge() { return age; }

public void setAge(int age) { this.age = age; }

@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(firstName, person.firstName) && Objects.equals(lastName, person.lastName); }

@Override public int hashCode() { return Objects.hash(firstName, lastName, age); }}

Page 20: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Data classes

data class Person( var firstName: String, var lastName: String, var age: Int

)

Page 21: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Properties

class Person {

var firstName: String = ""

}

Page 22: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Properties

public class Person {

private String firstName;

public String getFirstName() {

return firstName;

}

public void setFirstName(String firstName) {

this.firstName = firstName;

}

public Person() { this.firstName = ""; }

}

Page 23: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Make val not var

var mutable: String

val immutable: String

Page 24: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Properties

class Person(

var firstName: String

)

Page 25: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Properties

public class Person {

private String firstName;

public String getFirstName() {

return firstName;

}

public void setFirstName(String firstName) {

this.firstName = firstName;

}

public Person(String firstName) {

this.firstName = firstName;

}

}

Page 26: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

val canBeNull: String?

val notNull: String

Page 27: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

fun nullability(str: String?) {

val dot = str.indexOf(".")

}

Page 28: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

fun nullability(str: String?) {

val dot = str.indexOf(".")

}Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

Page 29: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

fun nullability(str: String?) {

val dot = str!!.indexOf(".")

} Non-null asserted call

May throw NullPointerException

Usually a bad style,use only when you know what you are doing

Page 30: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

fun nullability(str: String?) {

val dot = str?.indexOf(".")

} Safe call

The result will be null if str is null

Page 31: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

fun nullability(str: String?) {

val dot = str?.indexOf(".") ?: 0

} Elvis operator

The result will be 0 if str?.indexOf() returns null

Page 32: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Null safety

fun nullability(str: String?) {

val dot = str?.indexOf(".") ?: throw Exception()

}

Page 33: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Type casts

fun cast(obj: Any) {

if (obj is String) {

val dot = obj.indexOf(".")

}

} Smart cast

obj is String inside ‘then’ branch

Page 34: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Type casts

fun cast(obj: Any) {

val str = obj as String

val dot = str.indexOf(".")

}

Page 35: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Type casts

fun cast(obj: Any) {

val str = obj as? String

val dot = str.indexOf(".")

}

Safe cast

str is null if obj is not a String

Page 36: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Extension functions

fun Int.days(): Period = …

fun Period.ago(): Date = …

3.days().ago()

2.months().later()

Page 37: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Extension properties

val Int.days: Period

get() = …val Period.ago: Date

get() = …

3.days.ago

2.months.later

Page 38: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Lambda expressions

val list = listOf<Int>()

list.filter({ it > 0 })

Page 39: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Lambda expressions

val list = listOf<Int>()

list.filter { it > 0 }

Page 40: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Lambda expressions

val list = listOf<Int>()

list.filter { it > 0 }.map { it*2 }

Page 41: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

inline functions

inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean):

List<T> {

val result = mutableListOf<T>()

for (it in this) {

if (predicate(it)) {

result.add(it)

}

}

return result

}

Page 42: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

inline functions

inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean):

List<T> {

val result = mutableListOf<T>()

for (it in this) {

if (predicate(it)) {

result.add(it)

}

}

return result

}

Page 43: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Anko is a Kotlin library which makes Android application development faster and easier.https://github.com/Kotlin/anko/

Anko

Page 44: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Anko

Anko Commons: a lightweight library with helpers for:Intents, Dialogs and toasts, Logging, Resources and dimensions

Anko Layouts: a fast and type-safe way to write dynamic Android layouts

Anko SQLite: a query DSL and parser collection for Android SQLite

Anko Coroutines: utilities based on the kotlinx.coroutines library

Page 45: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Anko

verticalLayout {

val name = editText()

button("Say Hello") {

onClick { toast("Hello, ${name.text}!") }

}

}

Page 46: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

A set of Kotlin extensions for Android app developmenthttps://github.com/android/android-ktx

Android KTX

Page 47: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Android KTX

sharedPreferences.edit()

.putBoolean("key", value)

.apply()

Page 48: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Android KTX

sharedPreferences.edit {

putBoolean("key", value)

}

Page 49: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Android KTX

val spannedString = buildSpannedString {

bold { "Hello" }

italic { "KTX!" }

}

Page 50: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Kotlin Android Extensions

Page 51: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Kotlin Android Extensions

apply plugin: 'kotlin-android-extensions'

Page 52: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

View binding

findViewById<TextView>(R.id.label)

Page 53: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

View binding

// Using R.layout.activity_main from the 'main' source set

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

findViewById<TextView>(R.id.label)

Page 54: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

View binding

// Using R.layout.activity_main from the 'main' source set

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

findViewById<TextView>(R.id.label)

Page 55: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

View binding

// Using R.layout.activity_main from the 'main' source set

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

findViewById<TextView>(R.id.label)

label.text = "Hello!"

Page 56: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

View binding

// Using R.layout.activity_main from the 'main' source set

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

label.text = "Hello!"

Page 57: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Parcelable

import android.os.Parcelable

import kotlinx.android.parcel.Parcelize

@Parcelize

data class Person( var firstName: String, var lastName: String, var age: Int

) : Parcelable

Page 58: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Coroutines (Kotlin 1.1)

Asynchronous programming made easy

Write asynchronous code in synchronous style

Page 59: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Coroutines (Kotlin 1.1)

Asynchronous programming made easy

Write asynchronous code in synchronous style

val team = api.team().await()

val lead = api.profile(team.lead.id).await()

Page 60: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Multi-platform projects

Share code between different platforms

JVM + AndroidJS

In development:iOS/macOS/Windows/Linux Kotlin/Native

Page 61: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Thank you!

Victor Kropp@kropp

victor.kropp.name

Page 62: @kropp ROME - APRIL 13/14 2018 Kotlin for Android developers for Android developers.pdf · Kotlin for Android developers Victor Kropp, JetBrains @kropp ROME - APRIL 13/14 2018. Kotlin

Questions?

Victor Kropp@kropp

victor.kropp.name