12/04/18

How did Yogiyo Apply Kotlin?

By TaeHwan Kwon

RGP Korea operates both Yogiyo (YGY) and Baedaltong (BDT) service. Among these two services, I am in-charge of YGY’s service and recently I’ve been using Java and Kotlin. I applied about 14% of Kotlin on YGY app, and I would like to explain about why it was introduced and how I resolved learning curve issues.

Kotlin

After JetBrain Company announced Kotlin for the first time in 2011, official 1.0 version was released in 2016, and currently they released 1.1.6 version. Since 2011, stabilization has been going on for five years, and now Kotlin has been stabilized to a state that is just right to use for actual development instead of using Java. In 2017, Google I / O adopted to use Kotlin in parallel with Java, which is the main language for Android.

I searched for Kotlin’s usage rate, which was previously not available on the Google I / O application page, and I had much expectations, but even within Google only certain people were aware about it. On Google Blog, it explained about why Kotlin was adopted, and there were cases where well-known companies, such as Expedia, Flipbard, Pinterest, Square, etc., had applied it onto their real product, and it explained that they’ve adopted to use it due to stability.

Particularly, I was very satisfied with Safety Nullable, which is one of the advantages I learned while studying Kotlin for about a year. Whereas there are restrictions in using new techniques, such as Lambda and Streaming, with Java, I was very satisfied when I learned about Kotlin as it didn’t have such restrictions. I attached a photo that I personally took on the day of the event.

Applying Kotlin on YGY

I needed to go through the following processes:

  • Persuasion
  • Adoption
  • What I had to do about the learning curve?

Persuasion

Persuading was easier than I thought. Since I applied Kotlin after Google I / O, it was very easy to persuade. Previously, we decided to use it on YGY’s Owner App (App made for YGY Restaurant Owners to accept orders) only, but Google I/O also made it possible for us to use it on YGY app, which is targeted for general users.

As I had already learned about Kotlin, I chose productivity with the burden of verifying stability. I’ve been applying Kotlin to a real project for about six months, and I was able to maintain higher productivity rate than using Java.

However, although Kotlin provides a technique to avoid NullPointerException, in the beginning there faced a lot of NullPointerExceptions due to certain mistakes I made.

Adoption

The first part of the process was to convert a class I worked on, prior to Google I / O, from Java to Kotlin. It was not a long ViewModel, and I had already separated the role to handle just as a single part. I worked on it without difficulties. First, I started out by personally applying Kotlin to a project myself.

What I had to do for the learning curve?

Of course I can apply Kotlin on my own. However, what I needed was my team members and team leader to apply it as well. Fortunately, my team had interest in Kotlin and already learned a little about it. And, the web developer used Kotlin without difficulty, and he was able to use Kotlin more easily than myself without any big problems. Rather, I experienced errors that I had not experienced in a year, and I learned how to go about with better grammar.
I was able to persuade more easily than I anticipated, and was able to have Kotlin applied. Learning costs are involved when something new is applied. I believe cost of studying depends on how much one has interest in the subject, and I find that there is nothing as good as applying something at the company. When you go home, one tends not to study, so it is best to study during the time that you are able to.

Be the first to initiate

Please be sure to watch Pinterest – Christina Lee and Jake Wharton’s session among Google’s I / O sessions.

This session explains about Pinterest’s best method to introduce something new. Even though it may increase productivity, and though it may be a good language, ultimately I have to persuade team members to work on it with me. The best way to do that is to start by working on it myself, then persuade others one by one. Rather than just talking, you need to concretely figure out why it’s good to use, then persuade your team members and approach it so that everyone can gain and win-win out of it. Ultimate best option would be to persuade the superior member and apply a new method. Such methods are briefly explained in the video.

In the end, I should be able to explain why it is efficient and why it is good, instead of using it just because I am cool. If you were to work on it alone, you wouldn’t need to do this (because whatever you choose is the answer). But, I recommend this video, because it is the people who works with you that needs to be persuaded.

The bottom line is, if you really want to try something new, then it shouldn’t be “let’s just do it,” but it would be better to opt by trying it out yourself first and then persuading others.

NullPointer Exception

Even though I studied Kotlin for 1 year, I faced NullPointerException (NPE). I had used Kotlin to decrease NPE, but I overlooked the following:

  • Java: You can create a variable that can always be a null.
  • Kotlin: The base is that nullable is not allowed. You need to allow null by adding a “?”

I faced an issue, because I did not use Safety Nullable, which is one of the advantages of Kotlin. If I had only added a “?”, then it would have been a Nullable, but it turned into a NotNull.

Fortunately, Android Support Library 26 and above fortified on where Nullable is necessary.

If you don’t define Nullable, then problem occurs when you call a method created in Java using Kotlin. There is no problem, if a variable that is Nullable has a value when it is sent using Kotlin method, however if a null is entered, then a NullPointerException would occur in runtime.

The code below pertains to something like this. If I were to add a simple sample, two NotNull variable strings are received and it merges into a character.

// class name String.kt
fun merge(a: String, b: String) = "$a $b"

It you call the above merge method from Kotlin file, then “a” is a nullable and immediately creates an error.

(In actuality, it would have been normal that an error does not occur if you decompile since it is a Java code.)

class SampleTest {
  val a: String? = null

  @Test
  fun test() {
    StringKt.merge(a, "BC")
  }
}

// But, the part that I made a mistake on was calling Kotlin from Java.  
public class SampleTest {

  private String a = "A";
  private String b = "B";

  @Before
  public void setUp() { a = null; }

  @Test
  public void sample() {
      System.out.println("merge " + StringKt.merge(a, b));
    }
}

In Java, it is possible to change value of a variable at any time, and it is possible to apply a null. This is the value that you would receive through the API, and if the value is a null, then runtime error is inevitable and you will face an error as follows:

java.lang.IllegalArgumentException:
Parameter specified as non-null is null:
 method kr.co.yogiyo.myapplication.StringKt.merge

In order to avoid NullPointerException

In the end, you should do the following to avoid NullPointerException. When StringKt.merge (a,b) is called, then either you need to check whether the command is a NotNull and then pass the value or handle it as an exception by using try/catch.

To avoid NullPointerException

public class SampleTest {

  // omit ...

  @Test
  public void sample() {
    try {
      System.out.println("merge " + StringKt.merge(a, b));
    } catch (NullPointerException e) {}

    // or
    if (a != null && b != null) {
      System.out.println("merge " + StringKt.merge(a, b));
    }
  }
}

However, if you call StringKt.merge from 10 places, then it’s too troublesome as you will need to handle all 10 spots.

Therefore, it is more convenient to treat methods that is called as below as exceptions. The receiving-end should allow @Nullable and this should be used. Then, the sender does not need to take care of any parts, and the receiving-end returns based on its discretion.

// class name String.kt
fun merge(a: String?, b: String?) = "${a ?: ""} ${b ?: ""}"

How did we study Kotlin at YGY?

I studied Kotlin for nearly a year. But, I could not apply Kotlin just on my own, as a team member would need to modify it if I am not around. Therefore, there was a need to reduce learning curve among team members. The Team Leader was able to use it on his own to some degree, and he was good enough that he only asked about certain areas that he was unsure, and our team members were able to learn Kotlin through pair programming for about a month.

  1. Conduct pair programming
  2. First create classes using Java
  3. Code conversion by using Java to Kotlin convert
  4. If you already have a Kotlin file, create a separate temp.java file, and copy and paste. Support areas that are insufficient.
  5. Team members were able to personally use Kotlin once they were somewhat skilled. We pair programmed for about 1 month and worked on it together, and it was our first time applying Kotlin. Fortunately, by working in this fashion, the process enabled our team members to use Kotlin to a degree where they could use it well. Also, I was able to reduce codes for areas that I wasn’t aware of before.

To make appropriate use of pair programming, less time needs to be spent together, only look over areas that the other person does not know, then this would be a good way to grow.
Luckily, a team member had been with the company for a longer period than myself, and he was able to meticulously look over areas that were missing for me.

What were the conditions for converting?

It is necessary to convert Java to Kotlin. It would have been nice to take some time and work on everything using Kotlin, but that would take a lot of time so it is faster to just create a new one. However, as we cannot do that at the company, we converted it using the following method:

  • Run based on project units
  • Refactor existing codes

If one out of the two conditions above is applied, then a new package and packet is given, and we would then work on it.

New package condition, which is posted on my personal blog called “Package Structuring Method,” was used at my company as well. As the classes are grouped by views at time of code modification, then only one package needs to be checked, and it can be quickly fixed without having to move around too much. Even if you need to modify the ViewHolder that belongs to N Fragment of N Activity, then the advantage is that you can quickly understand and modify if the package name is made well.

Now, on YGY and YGY Owner’s App

We are in the process of applying Kotlin in full-swing on both YGY app and YGY’s Owner’s App. As of this time-point that I am writing, Kotlin is applied to about 14% of YGY’s Android App and any newly added areas are mostly worked on using Kotlin.

Most of the time, YGY’s Owner app was managed by a single team member. Right now Kotlin is applied through pair programming.

GitHub lets you know % of language used based on marster. So, I was able to check the above results. Even if additional jobs are handled, the rate would not go up if it is not merged on marster, but for now we’ve applied it at the above rate.

So, then?

This is the recent Restaurant List that we worked on. In order to remove existing legacy code we created everything new, and handled it by using Kotlin. Even Activity/ViewPager/Fragment were newly created using Kotlin.


Existing layout did not only weigh heavy, but there were a lot to be handled while having to move around. Currently, the following screen is displayed to some users as it is under A / B test.
I think productivity of Kotlin itself is high. For those who study it for the first time, experiencing some learning curve would be natural. However, if you are familiar with Java, there should be no problem learning Kotlin. Particularly, Kotlin can be more easily applied if you are a developer that used to use scripts or functions. After Google adopted it as an official language, more people are learning about Kotlin, and I notice that it’s being applied to actual projects.

Ultimately the people that one is working with needs to be persuaded in order to lead it to a better direction…