KOTLIN
Turbinando o Desenvolvimento Android Rafael Toledo
@_rafaeltoledo
Slide 2
Slide 2 text
POR QUÊ?
Slide 3
Slide 3 text
JETBRAINS
INICIADA EM 2010 PELA
é uma linguagem de programação
segura e acessível
além de ser muito pragmática
Slide 4
Slide 4 text
O QUE É?
•Estaticamente tipada
•Inspirada por Java, Scala, C#, Groovy
•Targets:
•JVM / Android
•JavaScript
•Nativo
Slide 5
Slide 5 text
LINHAS DE CÓDIGO EM KOTLIN
no Github
Slide 6
Slide 6 text
GOOGLE I/O 2017
Slide 7
Slide 7 text
APLICAÇÕES
• Mobile
• Client Side
•Web
•Desktop
• Server Side
Slide 8
Slide 8 text
BENEFÍCIOS
• Familiaridade com C#, Java, JavaScript, facilitando a adoção
• Interoperabilidade com a plataforma
• Java - JVM
• JavaScript
• Nativo - Interoperabilidade com C
Slide 9
Slide 9 text
CONVENÇÕES
• Segue as convenções de código do Java
• Tipos em caixa alta - MeuTipo
• Métodos e Properties em caixa baixa camelCase
• Ponto e vírgula opcional*
• Pacotes seguem a notação reversa
• Múltiplas classes por arquivo são permitidas
• Pacotes não precisam seguir a estrutura de pastas
Slide 10
Slide 10 text
FERRAMENTAL
• JDK
•Versão 6, 7, 8 e 9
• Compilador Kotlin
• Editor ou IDE
• IntelliJ IDEA, Android Studio, Netbeans, Eclipse
Slide 11
Slide 11 text
CARACTERÍSTICAS
Slide 12
Slide 12 text
DATA CLASSES
public class User {
private String name;
private String email;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Slide 13
Slide 13 text
DATA CLASSES
data class User(val name: String, val email: String)
Slide 14
Slide 14 text
MÚLTIPLAS CLASSES POR ARQUIVO
data class User(val name: String, val email: String)
data class Order(val id: Int, val user: User)
data class Address(val street: String)
Slide 15
Slide 15 text
PROPERTIES
var simple: Int?
val inferredType = 1
val isEmpty: Boolean
get() = this.size == 0
var stringValue: String
get() = this.toString()
set(value) {
splitAndAssign(value)
}
var privateSetter: String = "a"
private set
var annotated: Any? = null
@Inject set
Slide 16
Slide 16 text
NULL SAFETY
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle("Not so Awesome Java");
}
EXTENSÕES
override fun onCreateViewHolder(parent: ViewGroup,
viewType: Int): ViewHolder {
return ViewHolder(parent.inflate(R.layout.item_list))
}
parent.inflate(R.layout.item_list)
parent.inflate(R.layout.item_list, false) // Mesma coisa
parent.inflate(R.layout.item_list, true)
Slide 27
Slide 27 text
TYPE ALIAS
public class Interceptor implements okhttp3.Interceptor {
...
}
Slide 28
Slide 28 text
TYPE ALIAS
import okhttp3.Interceptor as OkHttpInterceptor
...
class Interceptor: OkHttpInterceptor {
...
}
Slide 29
Slide 29 text
SINGLETON
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
private Singleton() { }
}
Slide 30
Slide 30 text
SINGLETON
object Singleton {
...
}
Slide 31
Slide 31 text
LAMBDAS
public interface Callback {
void onFinish(Result result);
}
public void asyncRequest(Callback callback) {
...
callback.onFinish(result);
}
Slide 32
Slide 32 text
LAMBDAS
asyncRequest(new Callback() {
@Override
public void onFinish(Result result) {
Log.i("Callback", "Result was " + result.status());
}
});
Slide 33
Slide 33 text
LAMBDAS
asyncRequest(result ->
Log.i("Callback", "Result was " + result.status()));
// Depende de Retrolambda, Jack (plugin 2.x) ou plugin 3.+
Slide 34
Slide 34 text
LAMBDAS
fun asyncRequest(callback: (Result) -> Unit) {
...
callback(result)
}
asyncRequest { result ->
Log.i("Callback", "Result was ${result.status()}")
}
Slide 35
Slide 35 text
LAMBDAS
fun asyncRequest(callback: (Result) -> Unit) {
...
callback(result)
}
asyncRequest {
Log.i("Callback", "Result was ${it.status()}")
}
Slide 36
Slide 36 text
LAMBDA - PARÂMETROS NÃO UTILIZADOS
fun loadProduct(id: Int) {
api.fetchProduct(id) { (_, name, date) ->
title.text = name
createdOn.text = date.format()
}
}
Slide 37
Slide 37 text
TYPE ALIAS
typealias Length = Double
typealias Weight = Double
typealias Action = (T) -> Unit
typealias Multimap = Map>
Slide 38
Slide 38 text
DESESTRUTURANDO CLASSES
data class User(val username: String, val email: String)
fun printUserData() {
val (username, email) = fetchUser()
println("${username}: ${email}")
}
Slide 39
Slide 39 text
INTEROPERABILIDADE COM JAVA
retrofit.create(MyApiInterface::class.java)
@Rule @JvmField
val activityRule = ActivityTestRule(
MainActivity::class.java)
Slide 40
Slide 40 text
COROUTINES - EXPERIMENTAL
• Código assíncrono com cara de síncrono
• É basicamente uma "thread" (só que bem mais leve) que é pausada e
retomada posteriormente
"We think that now we have got a great design of coroutines for
Kotlin, but we realize that it has not been battle-tested enough."
INTENTS
ctx.startActivity(intentFor("id" to 1)
.singleTop())
makeCall("1406")
browse("https://google.com")
email("foo@bar.com", "Subject", "Body")
Slide 50
Slide 50 text
TOAST & LOG
toast("Hello")
toast(R.string.hello)
longToast("Hello again, because this toast is so long")
info("Hello")
warn(0)
debug("Another log")
Slide 51
Slide 51 text
ANDROID
EXTENSIONS
mais um pouco de comodidade pro Android
Slide 52
Slide 52 text
ANDROID EXTENSIONS
Adeus ao findViewById()
import kotlinx.android.synthetic.main.activity_main.*
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContextView(R.layout.activity_main)
textView.setText("It's a kind of magic!")
}
Slide 53
Slide 53 text
REFERÊNCIAS & LINKS
Blog Oficial
blog.jetbrains.com/kotlin
anko
github.com/kotlin/anko
Blog do Antonio Leiva
antonioleiva.com
Kotlin Koans
kotlinlang.org/docs/tutorials/koans.html
Slide 54
Slide 54 text
REFERÊNCIAS & LINKS
Livro: Kotlin for Android Developers
leanpub.com/kotlin-for-android-developers
Livro: Kotlin in Action
manning.com/books/kotlin-in-action
Kotlin Sandbox
github.com/rafaeltoledo/kotlin-sandbox