Fewer crashes and more stability with Kotlin

sjdvv
7 min readNov 24, 2020

Users expect to have a seamless experience with your app. Crashes can lead to an increase in poor reviews, uninstalls and even damaging your brand perception. From talking to the community we know that one of the main reasons to adopt Kotlin is safer code. In this post I’ll share a couple of the ways Kotlin improved the stability of a few of our partners’ code but we’ll also look at the results of some Google Play store stats and see if there’s a correlation between using Kotlin and the number of crashes (spoilers: there is!).

App quality

The quality of your app doesn’t only have an impact on your user experience. There are several other elements that will be affected by a high number of crashes:

  • App discoverability — Google Play store’s recommendations are composed of a mix of human curation and algorithmic calculations, of which quality is one of the largest considerations.
  • Brand — Your product performance can impact your ratings and reviews, which can impact brand perception.
  • Higher number of (engaged) users — Having improved organic traffic and brand perception can lead to better user acquisition and retention, which can also impact engagement and lower funnel metrics.

Apps built with Kotlin are 20% less likely to crash.

What role does Kotlin play in this? We looked at the top 1,000 apps on Google Play and we saw those that use Kotlin have 20% fewer crashes per user than those that don’t.

One example of this comes from the engineering team at Swiggy, where 74% of their code is in Kotlin — they saw a 50% reduction in crashes since moving new feature development to Kotlin.

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-0.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-2.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-3.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-4.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-5.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-6.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-7.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-8.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-9.html

https://ims.utoronto.ca/video/nfol/Rams-v-Buccaneers-1.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-0.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-1.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-2.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-3.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-4.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-5.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-6.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-7.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-8.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Buccaneers-9.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl01.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl02.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl03.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl04.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl05.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl06.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl07.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl08.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl09.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl10.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl11.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl12.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl13.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl14.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl15.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl16.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl17.html

https://ims.utoronto.ca/video/nfol/Rams-v-Bucc-liv-op-tv-nfl18.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm10.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm11.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm12.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm13.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm14.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm15.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm16.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm17.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm18.html

https://www.nationsreportcard.gov/codon/nfol/patra-nfl-kzm19.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm00.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm01.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm02.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm03.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm04.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm05.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm06.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm07.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm08.html

https://www.nationsreportcard.gov/codon/nfol/patra-Bucc-v-Rams-kzm09.html

https://joycedayton.com/sites/default/files/webform/r-b-00.html

https://joycedayton.com/sites/default/files/webform/r-b-01.html

https://joycedayton.com/sites/default/files/webform/r-b-02.html

https://joycedayton.com/sites/default/files/webform/r-b-03.html

https://joycedayton.com/sites/default/files/webform/r-b-04.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm00.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm01.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm02.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm03.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm04.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm05.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm06.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm07.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm08.html

https://ims.utoronto.ca/video/nfol/patra-Bucc-v-Rams-kzm09.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm10.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm11.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm12.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm13.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm14.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm15.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm16.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm17.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm18.html

https://ims.utoronto.ca/video/nfol/patra-nfl-kzm19.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl01.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl02.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl03.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl04.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl05.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl06.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl07.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl08.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl09.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl10.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl11.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl12.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl13.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl14.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl15.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl16.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl17.html

https://www.nationsreportcard.gov/codon/nfol/Rams-v-Bucc-liv-op-tv-nfl18.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv70.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv71.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv72.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv73.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv74.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv75.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv76.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv77.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv78.html

https://ims.utoronto.ca/video/nfol/bucca-vs-rams-liv79.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv70.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv71.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv72.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv73.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv74.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv75.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv76.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv77.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv78.html

https://www.nationsreportcard.gov/codon/nfol/bucca-vs-rams-liv79.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl01.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl02.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl03.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl04.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl05.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl06.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl07.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl08.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl09.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl10.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl11.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl12.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl13.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl14.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl15.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl16.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl17.html

https://shawee.io/shawee/amod/Rams-v-Bucc-liv-op-tv-nfl18.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-0.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-1.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-2.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-3.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-4.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-5.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-6.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-7.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-8.html

https://shawee.io/shawee/amod/Rams-v-Buccaneers-9.html

Avoiding NullPointerExceptions

The #1 cause of crashes on Google Play are NullPointerExceptions. In 2018, the Google Home team started writing all new features in Kotlin and saw a 33% decrease in Null Pointer crashes over one year.

Google Home saw a 33% decrease in NullPointerExceptions

To avoid NullPointerExceptions, you need to make sure that the object references you’re working with are non-null before calling methods on them or trying to access their members. In Kotlin, nullability is part of the type system. For example, a variable needs to be declared from the beginning as nullable or non-nullable. By making nullability part of the type system you don’t have to rely on your memory and knowledge of the codebase, or on compile time warnings (if you annotate your fields / parameters with @Nullable) but rather nullability gets enforced, so you’ll get compile time errors, not just warnings. For ways to handle nullability check out this page.

Avoiding common issues

There are a lot of issues that we developers introduce without realising and a lot of them can be quite subtle and hard to investigate. Here are just a few of these issues that are avoided when using Kotlin.

hashCode() and equals()

If two objects are equal, then their hashcode should be the same — but yet, it’s common to forget to implement one of these methods or to update them when new properties are added to the class. When working with classes whose role is to just hold data, use Kotlin data classes. With data classes hashCode() and equals() is generated for you by the compiler and therefore automatically updated when you change the class’s properties.

Structural vs referential equality

Are two objects structurally equal (have equivalent content) or referentially equal (their pointers are the same)? In the Java programming language, for primitives you would always use ==, therefore, a common mistake is to call == (referential equality) for objects as well, when you actually want to check if they are structurally equal (checked by calling equals()). First, Kotlin doesn’t have primitive types, it uses classes like Int or String; so this means that you don’t need to make this differentiation between objects and primitive types anymore as everything is an object. Second, Kotlin defined == for structural equality and === for referential equality so you won’t be checking for referential equality when you shouldn’t.

When if else if else if else is not enough

When working with enums, you often need to ensure that you’re covering all the possible cases. This leads to using a switch or a chain of if elses. When you modify your enum to add a new value, you then have to manually check each code snippet where you’re using the enum and make sure you’re handling the new case. But this is error prone. In Kotlin, you can rely on the compiler for this, if you’re using when as an expression: you’ll get a compiler error if you’re not covering all possible branches.

Conclusion

The stability of your app is important for your users and your brand. Start using Kotlin to reduce crash rates, keep your users happy and stay on top of your retention and acquisition by keeping a high app rating.

Read more about how you can Build Better Apps with Kotlin, and see how developers have benefited from Kotlin by reading our case studies. To make your first steps with Kotlin, one of the most loved languages in the world, check out our Getting started page.

--

--