I was trying to convert an Android project to Kotlin in Android Studio via the Kotlin plugin. If you haven’t read part one (you can always do it now), then I’ll briefly tell you that it’s up to you to choose how many classes to convert. I chose them all. The conversion caused numerous compilation errors and practically swayed me to convert one/two classes at a time. Even though solving compilation errors was a great way to learn, I still had an ambition – convert my MVP example project from Java to Kotlin code.

Therefore, I decided to attack it from another angle. My second approach was less messy – one or two compilation errors per conversion, albeit it took me a couple of hours to get everything working.

In the following post I will cover:

  • Adapter’s getView() runtime error, caused by the conversion
  • Kotlin pros/cons for Android developers
  • Verbosity comparison of Java vs Kotlin

TL;DR Conversion might cause errors but Kotlin will reduce NullPointerExceptions, and minify your code into a much more readable version.

TaskFragment’s Adapter Curve Bull

If you remember, the MVP example project is a simple To-do List. One of the main pitfalls I had after converting to Kotlin was that adding a new note to the list led to a crash.

Hello, Kotlin! Converting an Android Project – Part 2

Stack Trace:

FATAL EXCEPTION: main Process: com.example.android.architecture.blueprints.todomvp.mock, PID: 4124 java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter view
at com.example.android.architecture.blueprints.todoapp.tasks.TasksFragment$TasksAdapter.getView(TasksFragment.kt)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1280)
at android.widget.ListView.onMeasure(ListView.java:1188)
at android.view.View.measure(View.java:18788)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18788)

Something’s fishy in TaskAdapter’s getView method. I’ve placed a breakpoint on the first line of the method. However, the app still crashed and the breakpoint wasn’t encountered.

Let’s take a look at getView:

override fun getView(index: Int, view: View, viewGroup: ViewGroup): View {
  var rowView: View? = view
  if (rowView == null) {
    val inflater = LayoutInflater.from(viewGroup.context)
    rowView = inflater.inflate(R.layout.task_item, viewGroup, false)
  }

The view parameter is a non-null type (no ‘?’ after the ‘View’ type name makes it non-null). Now, if the view was created at some point before, we just need to update the values. But what if the view hadn’t been created yet? Then the exception makes sense.

Of course, the conversion process didn’t know that. It simply didn’t make the assumption that the parameter may be null. The fix is therefore pretty simple – we just need to declare ‘view’ as a nullable View type (view: View?).

Afterwards I deleted the getView() method altogether and let Android Studio generate the must-implement method for me. The method that was generated had the right nullable types:

override fun getView(i: Int, view: View?, viewGroup: ViewGroup?): View

The conversion maybe went wrong but the default behavior of Kotlin in Android Studio is right.

Following these footsteps, I went class by class and slowly converted my project to Kotlin success.

SafeDK In-App Protection

Pros: What I Liked When Converting to Kotlin?

Verbosity: Write less, accomplish more.

  1. no ‘new’ keyword
  2. Lambdas remove plenty of boilerplate code. Trade new OnClickListener with simple {  }. Also no need to be afraid of activity reference memory leaks: theses lambdas don’t reference outer class unless they explicitly have to.

Null safety: Language support for null types. We probably won’t get rid of all NPEs, but it is sure to reduce them.

Gradual change: It’s up to you to decide how much Kotlin you want your modules to be.

Bonus points

  1. Nothing type: you’re writing a method that doesn’t return (for instance, an infinite game loop that checks for user events). In Kotlin you can mark that with the ‘Nothing’ return type. It’s not such a big change, but it shows how much JetBrains is working towards a clear and readable code.
  2. You can return multiple values from a method or destruct an object of multiple properties into multiple variables.

Cons: Why not Kotlin Now?

Uncertain future – Even though JetBrains promise they will support everything that Google will throw at them, we can’t be sure. Google recently announced a change of the compilation process, combining all of the previous tools (javac, ProGuard etc.) into one – Jack (and Jill). Even though most of the apps are not supporting this compilation, it’s just an example of how radically things can change down the road. Most chances .class files and bytecode will always be suitable on the platform, thus keeping Kotlin safe and compatible, but you should ask yourself if you’re willing to take of waking up one morning to discover you need to spend time and manpower to fix compilation errors suddenly appearing.

Note for example that Android Studio 2.3’s first Canary release told developers to “wait with Kotlin. It’s not suitable yet.”

Operator overloading: Letting developers override operators might lead to ambiguity. It’s a more opinionated subject (almost as tabs vs spaces), but let’s consider the following example:

User userA = userB + userC - userD

Method count – Unfortunately, it’s still an issue in Android. Our research shows that the basic Kotlin package comes with a few hundred methods, and then it adds more depending on how much you use it. Had we written in plain Java, with all of its shortcomings, we could have spared those extra methods. For some it may be a small price to pay, for others it may be too big.

SafeDK X-Ray: Find the SDKs Within!

So… To Kotlin or Not To Kotlin?

Android has matured a lot these past few years. The standards are being raised every year with the adoption of architectural patterns (MVP, MVC, MVVM, MPB), data binding (RxAndroid) and better testing patterns. It’s developed using mostly Java 6 features (a 10 year old language, an almost has-been in this ever-changing industry), which is stable, predictable, great for enterprises and well, outdated.  If we were to peek into our competitors’ backyard, we would encounter a language similar to Kotlin embraced and praised by the developers, with the only drawback being breaking changes over different versions (ABI and API).

Kotlin is new, innovative, developed by a trusted big gun like JetBrains, and most of all – open source, which is a big plus.

On the other hand, there’s developers fatigue (take Javascript for example). Android is already abundant with different options and opinions about many topics and has plenty of possible libraries and SDKs to use. Another developing language can widen this gap of possibilities into a canyon of dev-suffering. It might be intimidating to a new Android dev trying to choose between MVP or MVVM, Java or Kotlin, Fragments or Custom views. Even if these choices are made by a senior Android dev, a junior dev interviewing for a job might be asked about. IMHO I think that all of these possibilities are also a sign of a strong community in progress.

Basically, I’m all for the practices that help write a more readable and maintainable code. Let’s be honest, we are reading code much more than writing it. If Kotlin idioms can make your code more readable I’m up for that. But we do write code quite often. In my experience, code is that quick to write, is hard to understand. Kotlin can pack code into lighter baskets, thus reducing the amount of code you read, but it’s up to the developer to write good coherent code with best practices in mind. Kotlin just makes it easier for you. Use it wisely.