kotlin for android - vali iorgu - mrready
TRANSCRIPT
Kotlin Featuresfor Android Developers
What is Kotlin?● Kotlin is not a platform (Xamarin, Cordova, etc.)
● It’s more like TypeScript or Swift
● Kotlin is a programing language built to run wherever Java runs
● It’s a pragmatic language, designed for developer productivity
Painless Java Interop● Kotlin was build to play nicely with Java
● Mix Java and Kotlin code in the same project
● You can still use all your favorite libraries in Kotlin
● The underlying Android Framework is the exact same
you would use in Java
Project Setup1. Install the IDE plugin
Project Setup2. Add the dependencies
buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }}
apply plugin: 'kotlin-android'
dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"}
Basic Syntax Overview
// in Kotlin types go at the end
var a: String = "Hello"
fun sayHello(): String { return "Hello"}
class MyActivity: Activity()
// Java equivalent
String a = "hello";
String sayHello() { return "Hello";}
class MyActivity extends Activity {}
Basic Syntax Overview
// in Kotlin
val a = 1a = 2 // ← compiler error
var b = 1b = 2 // ← this is ok
fun c() { }
// Java equivalent
final int a = 1;a = 2; // ← compiler error
int b = 1;b = 2; // ← this is ok
void c() {
}
Features you can use from day 1
1. Null safety and Smart Cast
Nullability is part of the type system and enforced by the compiler
val a: String = null // ← syntax error
val a: String? = null // ← this is ok
1. Null safety and Smart Cast
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) savedInstanceState.getString(...) // ← syntax error savedInstanceState?.getString(...) // ← this is ok
savedInstanceState!!.getString(...) // ← this is also ok but will // throw on null
}
1. Null safety and Smart Cast
Once the compiler determines a value can't be null, you can use it as such
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
if(savedInstanceState != null) { // The compiler now knows it can't be null here savedInstanceState.getString(...) savedInstanceState.getInt(...) }}
1. Null safety and Smart CastWe can use the “Elvis Operator” to provide default values
// in Kotlinval someValue = savedInstanceState?.getString("value") ?: "default"
// Java equivalentString someValue;If (savedInstanceState != null &&
savedInstanceState.getString("value") != null) { someValue = savedInstanceState.getString("value");} else { someValue = "default";}
2. Statements as expressionsIn Kotlin statements like if and when can be used as expressions
override fun getItemViewType(position: Int): Int { return when(items[position]) { is Title -> TYPE_TITLE is Description -> TYPE_DESCRIPTION else -> TYPE_UNKNOWN }}
2. Statements as expressionsreturn and throw are also expressions but return the Nothing type
fun renderWeatherCondition(condition: WeatherCondition?) { val iconRes = if (condition != null) { when (condition.type) { SUNNY -> R.drawable.ic_sunny RAINY -> R.drawable.ic_rainy else -> throw RuntimeException("Unknown condition $condition") } } else { return } //...}
3. Inline methods and lambdasThe Kotlin stdlib comes with a set of quite useful functional operations
val titles = movieList .filter { it.isFavorite } .sortedByDescending { it.rating } .map { it.title }
// Java equivalent
List<Movie> favoriteMovies = new ArrayList<>();for (Movie movie : movieList) { if(movie.isFavorite()) { favoriteMovies.add(movie); }}
Collections.sort(favoriteMovies, new Comparator<Movie>() { @Override public int compare(Movie o1, Movie o2) { return o1.getRating() - o2.getRating(); }});
List<String> titles = new ArrayList<>();for (Movie movie : favoriteMovies) { titles.add(movie.getTitle());}
3. Inline methods and lambdas● Methods in Kotlin can be marked as inline ● The body of the inline method is “copied” to the call site● Lambdas in these methods generate no overhead
inline fun <T> Iterable<T>.forEach(action: (T) -> Unit) { for (element in this) action(element)}
In Kotlin you can define functions what act on a specific receiver type
4. Extension functions
fun Context.getDrawableCompat(resId: Int): Drawable { return ContextCompat.getDrawable(this, resId)}
val logo = context.getDrawableCompat(R.drawable.ic_logo)
4. Extension functions
fun Context.share(text: String, subject: String = "") { val intent = Intent(Intent.ACTION_SEND) intent.type = "text/plain" intent.putExtra(Intent.EXTRA_SUBJECT, subject) intent.putExtra(Intent.EXTRA_TEXT, text) startActivity(Intent.createChooser(intent, null))}
Some more advanced features
5. Reified genericsKotlin has limited support for reified generics
// in JavaList<User> users = gson.fromJson(json, new TypeToken<List<User>>() {}.getType());
// in Kotlininline fun <reified T> Gson.fromJson(json: String): T { return fromJson(json, T::class.java)}
val users = gson.fromJson<List<User>>(json)
6. Receiver lambdas● Lambda parameters can be defined with an optional receiver type● Code inside these lambdas behaves as if defined in an extension function on
that type
inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
val intent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_SUBJECT, "Hi!") putExtra(Intent.EXTRA_TEXT, "Hello")}
6. Receiver lambdas
// in Java
db.beginTransaction();try { db.insert(...); db.update(...); db.delete(...);
db.setTransactionSuccessful();} finally { db.endTransaction();}
6. Receiver lambdas
fun SQLiteDatabase.inTransaction(block: SQLiteDatabase.() -> Unit) { beginTransaction(); try { block() setTransactionSuccessful(); } finally { endTransaction(); }}
6. Receiver lambdas
//in Kotlin
db.inTransaction { insert(...) update(...) delete(...)}
// Java equivalent
db.beginTransaction();try { db.insert(...); db.update(...); db.delete(...);
db.setTransactionSuccessful();} finally { db.endTransaction();}
6. Receiver lambdasThis feature is very useful for creating DSLs
val layout = verticalLayout { padding = dip(30) editText { hint = "Name" textSize = 24f } editText { hint = "Password" textSize = 24f } button("Login") { textSize = 26f }}
Upcoming in 1.1 - Coroutines
showLoading()
val someOperation = async { complicatedOperation() }val anotherOperation = async { complicatedOperation() }
val result = someOperation.await() + anotherOperation.await()
displayResult(result)
hideLoading()
Much more that we didn’t cover● Property delegation● Data classes● Sealed classes● Type aliases● Operator overloading● Destructuring operators● Infix functions● Named parameters● Class delegation● … and more
Resources● Official website: http://kotlinlang.org
● Online “IDE”: http://try.kotl.in
● Official Slack: http://slack.kotlinlang.org (~6000 members and counting)
● GitHub repo: https://github.com/jetbrains/kotlin
● “Design documents” for upcoming features: https://github.com/Kotlin/KEEP