infinum android talks #20 - benefits of using kotlin
TRANSCRIPT
We're an independent design & development agency.
infinum.co/android-sweetsFresh news from Droid zone, curated by Željko Plesac
Benefits of using Kotlin
DINO KOVAČ
BASIC INFO
• statically typed JVM language
• fully interoperable with Java
• developed by JetBrains
HISTORY
• in development since 2010
• stable version released at 15.2.2016.
• used in 10 projects internally at JetBrains
GOALS
• concise
• expressive
• toolable
• interoperable
• pragmatic
REAL EXAMPLES
MODELS
public static class LoginResponse { @Json(name = "userName") private String username; @Json(name = "token_type") private String bearer; @Json(name = "expires_in") private int expiresIn; @Json(name = "access_token") private String accessToken; @Json(name = "refresh_token") private String refreshToken; public LoginResponse(String username, String bearer, int expiresIn, String accessToken, String refreshToken) { this.username = username; this.bearer = bearer; this.expiresIn = expiresIn; this.accessToken = accessToken; this.refreshToken = refreshToken; } public String getUsername() { return username; } public String getBearer() { return bearer; } public int getExpiresIn() { return expiresIn; } public String getAccessToken() { return accessToken; } public String getRefreshToken() { return refreshToken; }}
class LoginResponse( @Json(name = "userName") val username: String, @Json(name = "token_type") val bearer: String, @Json(name = "expires_in") val expiresIn: Int, @Json(name = "access_token") val accessToken: String, @Json(name = "refresh_token") val refreshToken: String)
KOTLIN ANDROID EXTENSIONS
OPERATIONS WITH COLLECTIONS
private List<FilterTagListView> tagGroupViews() { List<FilterTagListView> filterTagListViews = new ArrayList<>(); for (int i = 0; i < filterContainer.getChildCount(); i++) { View view = filterContainer.getChildAt(i); if (view instanceof FilterTagListView) { filterTagListViews.add((FilterTagListView) view); } } return filterTagListViews;}
private fun tagGroupViews(): List<FilterTagListView> { return (0..filterContainer.childCount - 1) .map { i -> filterContainer.getChildAt(i) } .filter { childView -> childView is FilterTagListView } .map { it as FilterTagListView } }
/** * finds view group which contains given tag and marks tag selected within that group */public void addSelectedTag(CoupeTag tag) { FilterTagListView view = null; List<FilterTagListView> tagGroupViews = tagGroupViews(); for (FilterTagListView tagGroupView : tagGroupViews) { if (tagGroupView.getFilter().getTitle().equals(tag.getFilter().getTitle())) { view = tagGroupView; break; } } if (view != null) { view.setTagSelection(tag.getTitle()); if (filtersSelectedListener != null) { filtersSelectedListener.onSelected(getSelectedTags()); } }}
/** * finds view group which contains given tag and marks tag selected within that group */fun addSelectedTag(tag: CoupeTag) { val view = tagGroupViews().firstOrNull { view -> view.filter.title == tag.filter.title } view?.let { view.setTagSelection(tag.title) filterSelectedListener?.onSelected(getSelectedTags()?.toList()) } }
LISTENER INTERFACES
// adapterpublic interface OnCheckedChangeListener { void onCheckedChange(Genre genre, boolean isChecked);} public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) { this.listener = listener;}
if (listener != null) { listener.onCheckedChange(genre, isChecked);}
// activity this.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChange(Genre genre, boolean isChecked) { // TODO magic } });
// adaptervar onCheckedChangeListener: ((Genre, Boolean) -> Unit)? = null
onCheckedChangeListener?.invoke(genre, isChecked)
// activity genresAdapter.onCheckedChangeListener = { // TODO magic}
CONVENIENCES
List<AirDate> dummyAirdates = new ArrayList<>();dummyAirdates.add(new AirDate(ZonedDateTime.now(), 1));dummyAirdates.add(new AirDate(ZonedDateTime.now().plusDays(1), 2));dummyAirdates.add(new AirDate(ZonedDateTime.now().plusWeeks(1), 3));
val dummyAirDates = listOf( AirDate(ZonedDateTime.now(), 1), AirDate(ZonedDateTime.now().plusDays(1), 2), AirDate(ZonedDateTime.now().plusWeeks(1), 3) )
OTHERS
•setOf(), mapOf(), arrayOf() •emptyList(), emptySet(), emptyMap(), emptyArray()
• … plenty more
RISKS
WHAT IF JET BRAINS GOES OUT OF BUSINESS?
JETBRAINS
• 500+ employees
• fully bootstrapped
• steady revenue stream (subscription model)
• heavily invested in Kotlin
LANGUAGE STABILITY
SWIFT
OPEN SOURCE
I think it is fair to say that "open design" is slower and less predictable than "closed design”. However, the end result is significantly better, and therefore the tradeoff is worth it.
- CHRIS LATTNER, APPLE
WHAT IF GOOGLE BREAKS COMPATIBILITY?
Kotlin is interesting: works well with Java, more concise. JetBrains has done a nice job supporting this on android. But no plans to officially support anything new.
- ANWAR, ANDROIDENGTEAM
I don’t think we have any plans to break what already works there, but we don’t have plans to have a second, idiomatic-Kotlin version of the whole framework API surface area either.
- ADAM, ANDROIDENGTEAM
We don’t have any plans to move to a new language. Java has a lot of advantages to it and the versions 8, 9, and 10 have some pretty interesting stuff for developers.
- ANWAR, ANDROIDENGTEAM
CONCLUSION
• Kotlin can help you be more productive
• Kotlin is here to stay
• Be aware of the risks!
Thank you! [email protected] @DINO_BLACKSMITH
Visit infinum.co or find us on social networks:
infinum.co infinumco infinumco infinum