Kotlin: Integrate it with your complex Android project (Dagger, Mockito)

Introduction

In this article, I’m going to talk about some problems/situations I had to face while integrating Kotlin in a large and complex Android app and how to solve them. They might seem a bit simple once you know how it works but it took me some time to realize.

Let’s take a step back.

We all got super excited knowing that Kotlin is now officially supported by Google. One of the things I was waiting for was a seamless integration with Android Studio. And we got it!

A programming language can be extremely powerful but without a proper IDE, it can be tedious to develop for; take as example Swift and XCode.

At Capital One, we had a “what’s new at Google I/O ‘17” hackathon the other day. I wanted to do something with Kotlin and I thought that it could be painful due to the complexity of our Android project. What a surprise… It is not difficult at all!

Let’s kick off!

Add Kotlin support to your project

This is the easiest problem you’re going to face. Download Android Studio 3.0, look for the action (Cmd + Shift + A)Configure Kotlin in Project” and click enter… Voilà, That’s it! You’re good to go :)

Dagger

I thought Dagger was going to be the toughest part. I have Dagger working in Java and now with Kotlin… do I have to do something else?

The problem I found is that all Dagger examples in Kotlin don’t mix Kotlin and Java up. If you follow any tutorial on the Internet, you have to use the Kotlin Annotation Processor (kapt) in your gradle file and compile your project against it. I spent a lot of time trying to figure out how to integrate kapt with the java annotationProcessor… Wasted a lot of time!

The thing is… you don’t need kapt at all!

Everything just works with your current build.gradle!

compile "com.google.dagger:dagger:2.8"    
annotationProcessor "com.google.dagger:dagger-compiler:2.8"

Don’t waste your time making it more difficult than it is, That works for both Java and Kotlin.

In Java, you can do some injections with this code:

@Singleton
public class MyClass {

private final UserManager userManager;

@Inject
public MyClass(UserManager userManager) {
this.userManager = userManager;
}
}

You can do the same in Kotlin with:

@Singleton
class MyClass @Inject constructor(val userManager: UserManager) {

}
You can use Dagger annotations in Kotlin and in Java with the project being configured in Java. If you have a standalone Kotlin project, then you’d need kapt.

EDIT NOTE:

Nick Capurso was having some problems trying to generate the Dagger graph within Kotlin tests. If you need to address these kind of problems you might need kapt.

To fix it, you just need to update annotationProcessor with kapt and the generateStub option set to true:

kapt {
generateStubs = true
}

dependencies {
    ...
compile 'com.google.dagger:dagger:$daggerVersion'
kapt 'com.google.dagger:dagger-compiler:$daggerVersion'
}

Mockito

The same happens with Mockito. You don’t need to change anything in your build.gradle file! Just use the annotation as if it was Java. No changes required.

class MyClassTest {

@Mock
lateinit var mockUserManager: UserManager

lateinit var myClass: MyClass

@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
myClass = MyClass(mockUserManager)
}

@Test
fun testFunctionality() {

}
}

Easy, right? The only problem you might face is that Mockito cannot mock final classes and by default, Kotlin classes are.

You might have to use another mocking library or make the Kotlin class and methods open.

Proguard

There’s no need to add Kotlin classes to Proguard. Seems like it handles them automatically. Gradle runs the following tasks when creating a release build.

  • :app:compileReleaseKotlin
  • :app:compileReleaseKotlinAfterJava
  • :app:copyReleaseKotlinClasses

Adopting Kotlin in your organization

Do you work in a large organization and you feel like Kotlin is the way to go? I found Christina Lee’s talk at Google I/O ’17 quite good to help you adopting Kotlin in your organization. Don’t forget to shout out!

Summing up

Integrating Kotlin with your huge Android project is ridiculously easy! Everything works out of the box and you’re not required to do any weird changes.

Try it out! Switching to Kotlin is going to pay off at some point. I’ve already found use cases that reach Java limits and match perfectly with the benefits that Kotlin brings to our table. Super excited about it.

Thanks for reading,

Manuel Vicente Vivo

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.