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

Kotlin: A quick introduction

Kotlin: A quick introduction

Vinh Nguyen

May 04, 2018
Tweet

More Decks by Vinh Nguyen

Other Decks in Programming

Transcript

  1. AGENDA • Overview • Basic features • Kotlin in Android

    • In production: TripNow • Resources • Q&A
  2. 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
  3. History Time Version 2010 Kotlin project started 2016 Version 1.0

    2017 Google I/O, Official support 2018 Version 1.2.41
  4. 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
  5. 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!!”
  6. Properties Java (POJO) public class Artist { private String field

    = ""; public String getField() { return field;
 }
 public void setField(String field) { this.field = field;
 } }
  7. Data classes data class Artist( val id: Long, val name:

    String, var url: String, var address: String = "", var description: String = "None" )
  8. 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
  9. 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" }
  10. 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") }
  11. Functional Programming Lambda Function - (T) -> R Java public

    interface Callback<T> {
 void invoke(T result);
 }
 public void asyncOperation(int value, Callback<Boolean> callback) { ... callback.invoke(true);
 } asyncOperation(5, new Callback<Boolean>() { @Override public void invoke(Boolean result) { System.out.println("Result: " + result);
 } });
  12. 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") }
  13. Functional Programming Collections • Array, List • Set • Map

    • Iterable • … • filter { } • sort { } • map { } • zip { } • first { } • firstOrNull { } • flatmap { } • …
  14. 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”)
  15. Default arguments fun displayGreeting(message: String, name: String = "Guest") {

    println("Hello $name, $message") } displayGreeting("Welcome", "John") // Hello John, Welcome displayGreeting("Welcome") // Hello Guest, Welcome
  16. Interoperability // Java Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() { @Override public void

    onGenerated(Palette palette) { ... } }); // Kotlin Palette.generateAsync(bitmap) { palette -> ... }
  17. 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
  18. Introduction • Travel community • Search places, tours, blogs •

    Reviews & ratings • Create own travel trip (Web) • Future: Book tours, hotels,… • …
  19. 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 • …
  20. 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 • …
  21. Example Immutability and null safety data class TourSchedule( val id:

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

    = 0, val startDate: String = "", val endDate: String = "", val price: Double = 0.0 )
  23. 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; }
  24. 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; }
  25. 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); }
  26. 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; } } }
  27. 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)) }, {}) )
  28. Example Extended method fun TourScheduleEntity.toTourSchedule() = TourSchedule( id = this.id,

    startDate = this.startDate ?: "", endDate = this.endDate ?: "", price = this.price )
  29. 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) }
  30. Q&A