Slide 1

Slide 1 text

KOTLIN A QUICK INTRODUCTION Vinh Nguyen @ntvinh11586 Saigon, May 2018

Slide 2

Slide 2 text

AGENDA • Overview • Basic features • Kotlin in Android • In production: TripNow • Resources • Q&A

Slide 3

Slide 3 text

Overview

Slide 4

Slide 4 text

What is Kotlin? Kotlin island, Russia (59.9360229, 29.5408354,9)

Slide 5

Slide 5 text

What is Kotlin?

Slide 6

Slide 6 text

What is actual Kotlin? • Programming language • Created by JetBrains • Statically-typed language • JVM Based, compiles to Java bytecode, Javascript, or machine code (Native) • Object-oriented language, support functional programming • Simple, lightweight, interoperate • Is open source

Slide 7

Slide 7 text

History Time Version 2010 Kotlin project started 2016 Version 1.0 2017 Google I/O, Official support 2018 Version 1.2.41

Slide 8

Slide 8 text

Market share

Slide 9

Slide 9 text

Why Kotlin? “Concise, Safe, Interoperable, Tool-friendly” – kotlinlang

Slide 10

Slide 10 text

Basic Features

Slide 11

Slide 11 text

Null safety Artist artist = null;
 artist.print(); Java

Slide 12

Slide 12 text

Null safety var artist: Artist? = null
 artist.print() var artist: Artist? = null
 artist?.print() if (artist != null) { artist.print()
 } var artist: Artist? = null
 artist!!.print() Kotlin Won’t compile Will do nothing Smart cast Will crash var artist: Artist = null
 artist.print() Won’t compile

Slide 13

Slide 13 text

Mutability/Immutability var hello = “Hello world, var!” hello = “Hello world, again, var!!” Mutability Immutability val hello: String = “Hello world, val!” hello = “Hello world, again, val!!”

Slide 14

Slide 14 text

Properties Java (POJO) public class Artist { private String field = ""; public String getField() { return field;
 }
 public void setField(String field) { this.field = field;
 } }

Slide 15

Slide 15 text

Properties Kotlin class Artist(var property: String = "") { }

Slide 16

Slide 16 text

Data classes data class Artist( val id: Long, val name: String, var url: String, var address: String = "", var description: String = "None" )

Slide 17

Slide 17 text

Control flow: If var max = a if (a < b) max = b var max: Int if (a > b) { max = a } else { max = b } val max = if (a > b) a else b

Slide 18

Slide 18 text

Control flow: When when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { print("x is neither 1 nor 2") } } when { x.isOdd() -> print("x is odd") x.isEven() -> print("x is even") else -> print("x is funny") } value = when { x.isOdd() -> "x is odd" x.isEven() -> "x is even" else -> “x is funny" }

Slide 19

Slide 19 text

Control flow: For for (i in 1..3) { println(i) } for (i in 6 downTo 0 step 2) { println(i) } for (i in array.indices) { println(array[i]) } for ((index, value) in array.withIndex()) { println("the element at $index is $value") }

Slide 20

Slide 20 text

Functional Programming Lambda Function - (T) -> R Java public interface Callback {
 void invoke(T result);
 }
 public void asyncOperation(int value, Callback callback) { ... callback.invoke(true);
 } asyncOperation(5, new Callback() { @Override public void invoke(Boolean result) { System.out.println("Result: " + result);
 } });

Slide 21

Slide 21 text

Functional Programming Lambda Function - (T) -> R Kotin fun asyncOperation(value: Int, callback: (Boolean) -> Unit) { ... callback(true) } asyncOperation(5) { result -> println("result: $result") } asyncOperation(5) { println("result: $it") }

Slide 22

Slide 22 text

Functional Programming Collections • Array, List • Set • Map • Iterable • … • filter { } • sort { } • map { } • zip { } • first { } • firstOrNull { } • flatmap { } • …

Slide 23

Slide 23 text

Extension Function fun Context.toast(message: CharSequence) { Toast.makeText(this, message, duration).show() } context.toast("I'm a context") activity.toast("I'm an activity") service.toast("I'm a service”)

Slide 24

Slide 24 text

Default arguments fun displayGreeting(message: String, name: String = "Guest") { println("Hello $name, $message") } displayGreeting("Welcome", "John") // Hello John, Welcome displayGreeting("Welcome") // Hello Guest, Welcome

Slide 25

Slide 25 text

Interoperability // Java Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() { @Override public void onGenerated(Palette palette) { ... } }); // Kotlin Palette.generateAsync(bitmap) { palette -> ... }

Slide 26

Slide 26 text

Interoperability // Kotlin, ContextUtils.kt fun Context.toast(message: CharSequence) { Toast.makeText(this, message, duration).show() } // Java ContextUtilsKt.toast(context, “message”)

Slide 27

Slide 27 text

Kotlin in Android

Slide 28

Slide 28 text

Project configuration •~/build.gradle •ext.kotlin_version = '1.2.41' •org.jetbrains.kotlin:kotlin-gradle-plugin: $kotlin_version •~/app/build.gradle •apply plugin: 'kotlin-android' •apply plugin: 'kotlin-android-extensions' •org.jetbrains.kotlin:kotlin-stdlib- jdk7:$kotlin_version

Slide 29

Slide 29 text

Java compile

Slide 30

Slide 30 text

Kotlin compile

Slide 31

Slide 31 text

Gradle build times (no gradle daemon)

Slide 32

Slide 32 text

Gradle build times (daemon running)

Slide 33

Slide 33 text

Gradle build times (incremental, since 1.0.2) No file changed

Slide 34

Slide 34 text

Gradle build times (incremental, since 1.0.2) One independent file changed

Slide 35

Slide 35 text

Gradle build times (incremental, since 1.0.2) One core file changed

Slide 36

Slide 36 text

Demo

Slide 37

Slide 37 text

In production TripNow

Slide 38

Slide 38 text

Introduction • Travel community • Search places, tours, blogs • Reviews & ratings • Create own travel trip (Web) • Future: Book tours, hotels,… • …

Slide 39

Slide 39 text

Project target • Research new technologies • Apply the good architecture, clean code • Easy to maintain, following requirements changed faster • Make product stable, less errors, good performance • Cover by unit test • …

Slide 40

Slide 40 text

Kotlin usage • Make object immutability and safe from NULL • Reduce boilerplate code • Apply functional & lambda practice • Implement extended methods, toolkits, utils by using extension function • …

Slide 41

Slide 41 text

Example Immutability and null safety data class TourSchedule( val id: Int = 0, val startDate: String = "", val endDate: String = "", val price: Double = 0.0 )

Slide 42

Slide 42 text

Example Reduce boilerplate code data class TourSchedule( val id: Int = 0, val startDate: String = "", val endDate: String = "", val price: Double = 0.0 )

Slide 43

Slide 43 text

Example Reduce boilerplate code public final class TourSchedule { private final int id; @NotNull private final String startDate; @NotNull private final String endDate; private final double price; public final int getId() { return this.id; } @NotNull public final String getStartDate() { return this.startDate; } @NotNull public final String getEndDate() { return this.endDate; } public final double getPrice() { return this.price; } public TourSchedule(int id, @NotNull String startDate, @NotNull String endDate, double price) { Intrinsics.checkParameterIsNotNull(startDate, "startDate"); Intrinsics.checkParameterIsNotNull(endDate, "endDate"); super(); this.id = id; this.startDate = startDate; this.endDate = endDate; this.price = price; }

Slide 44

Slide 44 text

Example Reduce boilerplate code public TourSchedule(int var1, String var2, String var3, double var4, int var6, DefaultConstructorMarker var7) { if ((var6 & 1) != 0) { var1 = 0; } if ((var6 & 2) != 0) { var2 = ""; } if ((var6 & 4) != 0) { var3 = ""; } if ((var6 & 8) != 0) { var4 = 0.0D; } this(var1, var2, var3, var4); } public TourSchedule() { this(0, (String)null, (String)null, 0.0D, 15, (DefaultConstructorMarker)null); } public final int component1() { return this.id; } @NotNull public final String component2() { return this.startDate; } @NotNull public final String component3() { return this.endDate; }

Slide 45

Slide 45 text

Example Reduce boilerplate code @NotNull public final TourSchedule copy(int id, @NotNull String startDate, @NotNull String endDate, double price) { Intrinsics.checkParameterIsNotNull(startDate, "startDate"); Intrinsics.checkParameterIsNotNull(endDate, "endDate"); return new TourSchedule(id, startDate, endDate, price); } // $FF: synthetic method // $FF: bridge method @NotNull public static TourSchedule copy$default(TourSchedule var0, int var1, String var2, String var3, double var4, int var6, Object var7) { if ((var6 & 1) != 0) { var1 = var0.id; } if ((var6 & 2) != 0) { var2 = var0.startDate; } if ((var6 & 4) != 0) { var3 = var0.endDate; } if ((var6 & 8) != 0) { var4 = var0.price; } return var0.copy(var1, var2, var3, var4); }

Slide 46

Slide 46 text

Example Reduce boilerplate code public String toString() { return "TourSchedule(id=" + this.id + ", startDate=" + this.startDate + ", endDate=" + this.endDate + ", price=" + this.price + ")"; } public int hashCode() { int var10000 = ((this.id * 31 + (this.startDate != null ? this.startDate.hashCode() : 0)) * 31 + (this.endDate != null ? this.endDate.hashCode() : 0)) * 31; long var10001 = Double.doubleToLongBits(this.price); return var10000 + (int)(var10001 ^ var10001 >>> 32); } public boolean equals(Object var1) { if (this != var1) { if (var1 instanceof TourSchedule) { TourSchedule var2 = (TourSchedule)var1; if (this.id == var2.id && Intrinsics.areEqual(this.startDate, var2.startDate) && Intrinsics.areEqual(this.endDate, var2.endDate) && Double.compare(this.price, var2.price) == 0) { return true; } } return false; } else { return true; } } }

Slide 47

Slide 47 text

Example FP & Lambda compositeDisposable.add( selectedCityRepository.onRxSelectedCityUpdated() .observeOn(schedulerProvider.ui()) .doOnNext { view?.finishLoadingPages() } .doOnNext { loadHomeData() } .doOnNext { view?.scrollListToTop() } .doOnNext { view?.showSearchView() } .subscribe({}, { Log.e("log", Log.getStackTraceString(it)) }, {}) )

Slide 48

Slide 48 text

Example Extended method fun TourScheduleEntity.toTourSchedule() = TourSchedule( id = this.id, startDate = this.startDate ?: "", endDate = this.endDate ?: "", price = this.price )

Slide 49

Slide 49 text

Example Toolkits, Utils fun View.hideKeyboard() { context.hideKeyboard(this) } fun Context.hideKeyboard(view: View) { val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) } fun View.showKeyboard() { context.showKeyboard(this) } fun Context.showKeyboard(view: View) { val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager inputMethodManager.showSoftInputFromInputMethod(view.windowToken, 0) }

Slide 50

Slide 50 text

Learning resources • https://kotlinlang.org/ • https://try.kotlinlang.org/#/Examples/ • http://www.kotlinweekly.net/ • https://antonioleiva.com/kotlin/ • Book: Kotlin in Action • Book: The Joy of Kotlin (MEAP)

Slide 51

Slide 51 text

Q&A

Slide 52

Slide 52 text

Thank you!