“Using Kotlin in Your Android Production Code”

If you've read dozens of articles about using Kotlin for Android, and maybe even made your own pet project in it, but something’s keeping you from using Kotlin in your production code, this article is for you.

We won’t include the part about why Kotlin is better as compared to Java and how to configure your project for using Kotlin. If you need any help with this, simply go here.

Next time when you’re adding new modules to your project, and thinking of whether to use Kotlin or not, keep in mind the following:

Fact #1: Google has added Kotlin as their official programming language for Android development.

Fact #2: If you have a well structured Android project, which uses one of the common software architectural patterns (such as MVC, MVP or MVVM), you could safely start a new module in Kotlin. It’ll work with the existing Java code like a charm.

MVP and Kotlin (ReactiveX, Retrofit, RxBinding, etc.)

As an example, let’s make a simple MVP module, something as common as User Settings. Creating contract interfaces and fragments in Kotlin isn’t any different from Java, but, we know, "Talk is cheap. Show me the code." Here it is.

Contract:

interface UserSettingsContract {
    interface View{
        fun someSettingInputChanged():Observable<CharSequence>
        ....
        fun confirmButton():Observable<Void>
        ....
        fun setSomeSettingInput(text:String)
        ....
        fun showUi()
        fun showProgress()
    }
    interface Actions{
        fun resume()
        fun pause()
        fun save()
    }
}

Fragment

class UserSettingsFragment:BaseFragment{
    constructor() : super()
    private lateinit var activity: BaseActivity
    private lateinit var activityBus: Bus
    private var args: Bundle? = null
    private var settings : UserSettingsResponseDTO? = null
    private lateinit var view : UserSettingsContract.View
    private var presenter: UserSettingsContract.Actions? =null

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val root = inflater?.inflate(R.layout.wt_advanced_settings,container,false)
        activity = getActivity() as BaseActivity
        activityBus = activity.bus
        args = arguments
        settings = arguments?.getParcelable(Constants.SETTINGS_OBJECT)
        ....
        return root
    }

    override fun onStart() {
        activityBus.register(presenter)
        super.onStart()
    }

    override fun onStop() {
        super.onStop()
        activityBus.unregister(presenter)
    }
}

Nothing special, right?

In View (MVP) we often use benefits of Kotlin with() block:

private fun initView(){
        with(view){
            uiContainer = find(R.id.ui_container)
            progress = find(R.id.settings_progress)
            ....
            userName = find<EditText>(R.id.user_name)
            ....
        }
    }

Such a short notation: find(R.id.view_id) is not default in Kotlin, meaning you should definitely take a look at the Anko library - it could be very useful.

The good news is - JakeWharton’s RxBinding works just the way it always does:

override fun userNameChanged(): Observable<CharSequence> {
        return RxTextView.textChanges(userNameInput)
}

override fun confirmButton(): Observable<Void> {
        return RxView.clicks(confirmButton)
}

The best part, however, is in the Presenter. Often, when initializing view, we have to make two or more API calls and can alter the view state (hide it, change background colors, set label text, etc.) with received data only when all of the responses have been received. Usually, we use CombineLatest operator for such tasks in Java, but those huge stairs of code aren’t really that cool (anonymous Func and Subscriber objects with all methods etc.). With Kotlin, you can use different ReactiveX operators in a new, very expressive and readable manner. Have a look:

override fun resume() {
        view.showProgress()
        rx.Observable.combineLatest(authModel.accountStatus, profileModel.getUserSettings(user?.id),
                { t1, t2 -> (setValues(t1, t2)) }).subscribe(
                { v: Boolean ->
                    (run {
                        setupViewWithData()
                        view.showUi()
                        setupListeners()
                    })
                },
                { e: Throwable ->
                    (run {
                        Timber.e(e.localizedMessage)
                        activity.showErrorDialog(e)
                        view.showUi()
                    })
                }
}

In here, we’re passing two observables from models written in Java, which are based on the Retrofit 2.0 library’s ability to return rx.Observables from API interface, and as third argument we’re passing a lambda expression { t1, t2 -> (setValues(t1, t2)) } instead of the huge and uncomfortable Func2 objects call method. In subscriber object we also have a lambda expression, which is replacing its onNext() and onError() methods. If we’d used Java when writing this method, the code would’ve been more than twice as long and would also look awful.

Working with JakeWharton’s RxBinding library is almost the same for Kotlin and Java, but the final code is shorter and looks better:

view.someSettingSeekbarUserChanged()
                .skip(1)
                .subscribe(
                        {i:Int ->(view.setSomeSettingInput(i.toString()))})


view.someSettingInputChanged()
                .skip(1)
                .debounce(800,TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        {t: CharSequence ->
                            (run {
                                doYourStuffThere(t)
                                andThere(t)
                        })},
                        {e:Throwable->(run{
                            Timber.e(e.localizedMessage)
                        })}
                )

view.confirmButton().subscribe({save()})

Reading this type of code in Java is uncomfortable, because you need to skip all those husks of anonymous objects and method declarations. Using Kotlin makes it easier to write, read and understand the written code. And as you might have noticed, such tools like Timber or Hawk work perfectly in Kotlin classes.

One more useful feature of Kotlin is Extension functions. Many people are sceptical when reading about them at first, but as you start using Kotlin’s Extension functions more and more, you realize that this is a much more sophisticated way of coding as compared to Java. They allow you to extend an encapsulated object with the sort of behaviour that is necessary for you once, and just apply it again later.

For example, Context:

fun Context.color(res: Int): Int = ContextCompat.getColor(this, res)
fun Context.stringArray(res: Int): Array<String> = this.resources.getStringArray(res)

and use it like this:

val iconNames = (activity.stringArray(R.array.icons))

or ImageView:

fun ImageView.loadUrl(url: String) {Picasso.with(context).load(url).into(this)}

and usage:

imageView.loadUrl(url)

Definitely a killer feature that keeps us from returning to Java.

As you can see, there is nothing preventing you from writing MVP modules that you usually write in Java. Moreover, your code will become clear, expressive and short with Kotlin. If you want to see real examples of Kotlin implementation, please feel free to check out our GitHub page.

In the next part we’ll talk about using Kotlin with MVVM pattern and Android DataBinding, discuss its null safety, and give examples of how the “elvis operator” works in your project. Also we’ll have a look at all of the functional stuff with collections and lambdas (such as map, filter, single, etc), which could make every developer's life easier.