Prasham Trivedi

YAC - Some Kotlin Magic

5 minutes to read.

April 26, 2017

Part-1: Why I decided to develop a cleaner
Part-2: Why I chose Min Sdk 21 and Kotlin

In last part I have shown some example of Ceremonial Boilerplate we use daily to complete our tasks. And I stated that kotlin helps us to reduce this ceremonial boilerplate coding with their extension function and higher order functions (Where functions can have other functions as argument), these two are some of the most useful features of kotlin, that introduces lot of productivity itself.This post-while mostly focusing on how kotlin can reduce ceremonial boilerplate, it will also show some other good things that kotlin offers.

In last post I have stated two examples of ceremonies.

  1. Showing dialogs where not calling show() is problemeetic.
  2. Showing notifications where initiating notification manager and passing right arguments in notify() requires more focus then NotificationBuilder methods, which are more important.

In this post I will show you how I solved these problems in YAC.

Example 1: Showing Dialogs

The first example here is about showing dialogs. In Java, we follow these steps when we create a dialog.

  1. Initiate AlertDialog.Builder.
  2. Set Title (True for 90% of the case)
  3. Either
    1. Set a Message
    2. Set a view initiated from Java
    3. Inflate a view from XML.
  4. Set Positive and Negative buttons, while negative button just sits there because only OK or Yes doesn’t make sense.
  5. Optionally: If dialog should not be cancelable
    1. Get dialog object
    2. Call setCancelable and setCanceledOnTouchOutside with false.
  6. Most Important Step: Show the dialog

Many of us who are facing this for years, have developed a library method to tackle this common problem. In Java, while I was doing this manually all the time-Writing AlertDialog.Builder first, calling show method next and everything literally inbetween. I couldn’t imagine a library function for that, let alone writing it. But in Kotlin I have a library function for it. Look at below code.

This code defines 4 Extension Methods. showDialog (Extension of Context), positiveButton , negativeButton, neutralButton (Extensions of AlertDialog.Builder). Each method receives a Higher order function and powered by Default Arguments covering default use cases.

I won’t dive into each details here. Apart from official documents and koans, there are lot of blogs which explains all the details. I will only state how these things helped me in terms of productivity.

In this example showDialog does exactly what it needs to do, create alert dialog, apply logic, apply cancelation flags and show the dialog. But the beauty lies in how being it extension of Context allows me to call this method in any place where I can have context.

In programming, applying the core logic is more important then doing other ceremonies, and ideally our method should be able to receive that logic and execute it, no matter where this logic is defined. Higher Order Functions are perfect functionality to achieve that, the method(showDialog) receives a higher order function(builderFunction which is tied to AlertDialog.Builder class), and the method(showDialog) just blindly calls these higher order function to complete the ceremony, while actual logic in higher order function should be defined at the place where we’re calling the method.

And if in most of the times, If my positive button will show “OK”, my negative button will show “CANCEL”, which does nothing when being called, or by default my dialogs will be cancelable, I should not be forced to pass these values all the times to the method.Ideally I should pass positive button’s text only if it’s something other then the default value(“OK” in our case, which is going to be only once or twice in big projects).Default arguments helps us to cleanup the mess, which is created by absence of them (Like overriden methods or forced arguments).

If I define default arguments, I don’t have to pass the argument if I need the same value. It will just continue with those default arguments. Just like I called negativeButton method without any arguments, It will just show “CANCEL” in button, and do noting when clicked, while in Postive button’s case, I can change the label to “PICK FILES” and call an actual function.

Example 2: Showing Notificaitons

In this example of notification, everything which I have explained in dialog’s example applies as it is. Just difference is apply method. I have written this function much later in my process, When I wrote showDialog I didn’t know about apply method. In kotlin stdlib, apply works as extension function for given type T where it executes functions of T, and returnting the same T after applying all the operations. (Credit, this post)

Example 3: Callbacks

Managing callbacks are really more fun in kotlin then in Java. In Java, when operations done in Class A(Viewmodel, Dataset etc..), requires to update Class B(Fragment, Activity etc….), we use following steps.

  1. Define an interface somewhere with appropriate callbacks methods.
  2. Have a variable of that interface in Class A.
  3. Create a setter in class A.
  4. Pass the setter from Class B (In most cases Class B implements that interface itself)
  5. Comeback in Class A, Call appropriate method in appropriate times.
    • Optionally you need to have null checks (Just because Java ¯\(ツ)/¯)

But in Kotlin, using Higher level functions and lambdas it’s just easy to pass the functions as callbacks, and they don’t need any null checks if you have default function to start with.

Below example states the same thing, this example-also copied from YAC code- shows how I dealt with callbacks using Kotlin. Here example I passed three methods to addTab function which reacts to three different events, Success: with onFinished, Known Error (Maximum allowed tabs reached): onMaxTabsReached, Unknown Error: with onError. addTab calls appropriate method at appropriate times and in those actual methods I can do nearly anything.

There are lot of other benefits of Kotlin, and many blogs and communities are there to cover each and everything about it. If this post is enough to get you in kotlin, I recommend following resources to Start or Get hold on Kotlin.

  • Keddit Series - A medium series on Reddit Client development in Kotlin, Juan Ignacio Saravia has covered everything that can be done in kotlin: from initialization in Android studio to using dagger and unit testing.
  • Antonio Leiva’s kotlin related posts - I have been following his post since starting, those posts are the reason why I got confident enough to start a real project in kotlin. I would also recommend to purchase his kotlin book (Specially e-book) if it fits your budget.
  • Kotlin on Reddit
  • Kotlin Weekly - Newsletters are always a great way in our world to get updated and keep being relevant.
  • Fragmented Podcast episode on Kotlin - Fragmented is always a great podcast for any android developer, equally useful for newcomers and seniors. And their kotlin episode-right around 1.0 beta announement-is really like other episodes, to the point and has enough depth to cover.
  • Kotlin’s official community page

This is it for now, In next post I will focus on some more benefits kotlin has to offer, like when, null checks, lazy initialization etc…. (Why, read more no next post)

Next In the series: Kotlin Tips and Libraries

This Series states some stories behind the App I have developed, to try the app, click below to download it from playstore…

Get it on Google Play
YAC On Google Play
comments powered by Disqus