infinum android talks #20 - benefits of using kotlin

Post on 08-Apr-2017

58 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

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! DINO@INFINUM.CO @DINO_BLACKSMITH

Visit infinum.co or find us on social networks:

infinum.co infinumco infinumco infinum

top related