3. What this presentation cover
●
Kotlin introduction
●
What we can achieve by using Kotlin for Android
Development
4. What is Kotlin
●
Brand new programming language by JetBrains which targeting Java Platform,
open sourced and free to use
●
Kotlin is concise, safe, pragmatic, and focused on interoperability with Java code
– Works great with all existing Java libraries and frameworks
– Runs with same level performance as Java
●
Can be used for server-side development, Android apps, Desktop apps, and
much more. Anywhere Java runs
●
It’s statically typed programming language
●
Functional and Object Oriented
– First-class functions
– Immutability
– No side-effects
5. A bit History of Kotlin
●
Internal project of JetBrains unveiled in July 2011 after a year of development
– Seeking for language for future development
– Scala is great, but compile time and interoperability is obvious deficiency
●
Open sourced on February 2012 under Apache 2 license
●
First v1.0 released on February 15, 2016
– It takes 6 years for the first stable release
●
v1.1 just released on March 1, 2017
●
Named after Kotlin Island, near St. Petersburg, Russia.
Where most JetBrains’ Kotlin development team work
●
“Some part” of the language design is based on “Effective Java” book by
Joshua Bloch
6. Fun Facts?
●
C takes 1 years to first stable release
●
C++ takes 4 years
●
Java takes 4 years
●
Python takes 3 years
●
JavaScript only takes 10 days :-)
#DuaMingguJadi
8. Why Kotlin
●
(Android) Stuck on Java 6
– No streams
– No lambda, method references
●
Jack and Jill still on experimental
(Java 8 support for Android)
– No try-with-resources
9. Why Kotlin
●
(Android) Stuck on Java 6
– No streams Use RxJava
– No lambda, method references
●
Jack and Jill still on experimental
(Java 8 support for Android)
– No try-with-resources
10. Why Kotlin
●
(Android) Stuck on Java 6
– No streams Use RxJava
– No lambda, method references Use Retrolambda
●
Jack and Jill still on experimental
(Java 8 support for Android)
– No try-with-resources
11. Why Kotlin
●
(Android) Stuck on Java 6
– No streams Use RxJava
– No lambda, method references Use Retrolambda
●
Jack and Jill still on experimental
(Java 8 support for Android)
– No try-with-resources minSdkVersion = 19 or Use
Retrolambda
12. Why Kotlin
●
(Android) Stuck on Java 6
●
Inability to add methods to platform types in Java
– Achieved via Util class
●
Nullability problems (*NullPointerException) in Java
●
General verbosity / boilerplate code in Java
– Too much code to achieve minimal jobs
13. Taste of Kotlin
data class Person(val name: String,
val age: Int? = null)
fun main(args: Array<String>) {
val persons = listOf(Person("John Doe"),
Person("Logan", age = 49))
val oldest = persons.maxBy { it.age ?: 0 }
println("The oldest is $oldest")
}
// The oldest is Person(name=Logan, age=49)
Bye bye semicolon ;
Type after variable
Nullability and default value
Lambda expression
String template/interpolation
Data class
Named parameter
No “new”
14. Taste of Kotlin
●
Property declaration
– val (*value) for immutable property, ie once initialized
can’t be changed
– var (*variable) for mutable property, can be reassign
●
“fun” keyword to declare method/function
– So literally we are having fun when code in Kotlin
15. Taste of Kotlin
fun someFunction(): Unit { // functions always have return value
var say: String = "Kotlin is pragmatic language"
say = "also safe and concise"
val hello: String = "Domo Arigatou Mr. Roboto"
hello = "updated hello" // compile time error
return Unit
}
fun sum(x: Int, y: Int): Int {
return x + y
}
16. Taste of Kotlin
fun someFunction() {
var say = "Kotlin is pragmatic language"
say = "also safe and concise"
val hello = "Domo Arigatou Mr. Roboto"
// hello = "updated hello"
}
fun sum(x: Int, y: Int) = x + y // one liner
// Type inference
// compiler infer the type of properties without explicit declaration
17. 1. Null Safety
data class Contact(val name: String, var email: String? = null) {
constructor(name: String) : this(name, null)
}
fun main(args: Array<String>) {
val eko = Contact(email = "eko.suhariyadi@gmail.com",
name = "Eko Suhariyadi")
eko.name = null // compile error
eko.email = null // ok
}
18. Working with null
val eko = Contact("Eko Suhariyadi")
// if email is null return other value,
// with elvis operator ?:
val email: String = eko.email ?: "Have no email"
// cascading null safety
val emailStrSize = eko.email?.length
// safe scoping
eko.email?.let {
// send email
// only executed if email is not null
}
20. 2. Conciseness
Kotlin:
view.setOnClickListener {
// do something
}
view.setOnClickListener { view: View ->
// do something with the view
}
view.setOnClickListener { view ->
// do something with the view
}
21. 3. Data Class
●
Write POJO class in Java is quite verbose
– overloading constructor?
– getter and setter
– toString
– hashCode and equals
●
IDE could help for code generation
●
Or by using libraries such as Google’s AutoValue
22. 3. Data Classpublic class Todo {
private String description;
private Long createdAt;
private boolean done;
public Todo(String description, Long createdAt, boolean done) {
this.description = description;
this.createdAt = createdAt;
this.done = done;
}
// ...
23. 3. Data Classpublic class Todo {
private String description;
private Long createdAt;
private boolean done;
public Todo(String description, Long createdAt, boolean done) {
this.description = description;
this.createdAt = createdAt;
this.done = done;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Long createdAt) {
this.createdAt = createdAt;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
// ...
24. 3. Data Classpublic class Todo {
private String description;
private Long createdAt;
private boolean done;
public Todo(String description, Long createdAt, boolean done) {
this.description = description;
this.createdAt = createdAt;
this.done = done;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Long createdAt) {
this.createdAt = createdAt;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Todo todo = (Todo) o;
if (done != todo.done) return false;
return description != null ? description.equals(todo.description) : todo.description == null && (createdAt != null ? createdAt.equals(todo.createdAt) : todo.createdAt ==
null);
}
@Override
public int hashCode() {
int result = description != null ? description.hashCode() : 0;
result = 31 * result + (createdAt != null ? createdAt.hashCode() : 0);
result = 31 * result + (done ? 1 : 0);
return result;
}
@Override
public String toString() {
return "Todo{" +
"description='" + description + ''' +
", createdAt=" + createdAt +
", done=" + done +
'}';
}
}
25. 3. Data Class
data class TodoKotlin(var description: String,
var createdAt: Long,
var done: Boolean = false)
→ javap TodoKotlin.class
public final class com.codangcoding.havingfunkotlin.TodoKotlin {
public final java.lang.String getDescription();
public final void setDescription(java.lang.String);
public final long getCreatedAt();
public final void setCreatedAt(long);
public final boolean getDone();
public final void setDone(boolean);
public com.codangcoding.havingfunkotlin.TodoKotlin(java.lang.String, long, boolean);
public com.codangcoding.havingfunkotlin.TodoKotlin(java.lang.String, long, boolean, int,
kotlin.jvm.internal.DefaultConstructorMarker);
public final java.lang.String component1();
public final long component2();
public final boolean component3();
public final com.codangcoding.havingfunkotlin.TodoKotlin copy(java.lang.String, long, boolean);
public static com.codangcoding.havingfunkotlin.TodoKotlin copy$default(com.codangcoding.havingfunkotlin.TodoKotlin,
java.lang.String, long, boolean, int, java.lang.Object);
public java.lang.String toString();
public int hashCode();
public boolean equals(java.lang.Object);
}
26. 3. Data Class
●
Kotlin data class generate compiled code almost same with Java
POJO
●
But with extra method
– component(N) for destructure
– copy for “prototype pattern”
val todo = TodoKotlin("Sample TODO", System.currentTimeMillis())
val (description, createdAt, done) = todo // destructure
println("$description, $createdAt, $done")
// need to destruct description and done only
val (desc, _, finished) = todo
println("$desc, $finished")
// create new object by cloning from other
val copiedTodo = todo.copy(
description = "Copy from Sample TODO", done = true)
println("""|
|$todo
|vs
|$copiedTodo""".trimMargin())
27. 4. Extensions Functions
●
Ability to add functions or properties to existing class
without modify the class itself
●
In Java, we usually using static utility classes
let’s called it “util hell”
// java
public static void inflate(ViewGroup viewGroup, int layoutId) {
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
inflater.inflate(layoutId, viewGroup, false);
}
28. 4. Extensions Functions
// kotlin
fun ViewGroup.inflate(layoutId: Int) = LayoutInflater.from(this.context)
.inflate(layoutId, this, false)
// we can call the function like this
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val root = parent.inflate(viewType)
return ViewHolder(root, itemClick)
}
35. 5.x Higher Order Function
●
Function that takes functions as parameter or returns a function
fun listCalculator(numbers: List<Int>, calculator: (List<Int>) -> Int) =
calculator(numbers)
fun main(args: Array<String>) {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val sum = listCalculator(numbers, { numbers ->
var accumulate = 0
numbers.forEach { accumulate += it }
accumulate
})
val avg = listCalculator(numbers, { numbers ->
var accumulate = 0
numbers.forEach { accumulate += it }
accumulate / numbers.size
})
println("sum=$sum, avg=$avg")
}
36. 5.x Higher Order Function
●
If function is the last paramater, we can do this
fun listCalculator(numbers: List<Int>, calculator: (List<Int>) -> Int) =
calculator(numbers)
fun main(args: Array<String>) {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val sum = listCalculator(numbers) { numbers ->
var accumulate = 0
numbers.forEach { accumulate += it }
accumulate
}
val avg = listCalculator(numbers) { numbers ->
var accumulate = 0
numbers.forEach { accumulate += it }
accumulate / numbers.size
}
println("sum=$sum, avg=$avg")
}
37. 5.x Extension Function Expressions
●
Extension Functions – Functions added to a type
without modifying the original.
●
Function Expressions – Undeclared function
bodies used an as expression (ie. data/value)
●
Higher Order Functions – Function which takes
function as parameter or returns a function
43. 5.x Extension Function Expressions
inline fun SQLiteDatabase.useTransaction(func: SQLiteDatabase.() -> Unit) {
beginTransaction()
try {
func()
setTransactionSuccessful()
} finally {
endTransaction()
}
}
db.useTransaction {
delete("movie", "title = ?", arrayOf("Logan"))
}
// with inline keyword, code block will be inlined with caller code
// so, there is no overhead for creating lambda
44. 5.x Extension Function Expressions
●
Higher order functions is very convenience to create our own DSL
●
For Android developer
– There is anko library which brings android layout to kotlin
code, not xml
– Its faster than xml, because actually android xml layout will be
compiled to java code first
// anko Android layout DSL example
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}