Trying to Build Android MVP App in Kotlin

Eminarti Sianturi
AndroidPub
Published in
8 min readAug 19, 2017

--

Hello, here I’m going to post about Trying to Build Android App with MVP architecture in Kotlin, a new JVM language. I’ll try to explain Kotlin and it’s main features while developing this app. I hope it will help you to learn this language in the context of Android.

We will learn Kotlin covering topics like Properties and Fields, Data Classes, Null Safety, and also Android covering scenarios like Call API, Binding and Manipulating Views and more. I will assume that you already know Java and have experience in Android.

What is Kotlin ?

Kotlin is a programming and development language from JetBrains. They’re the folks behind the IntelliJ Java IDE and Kotlin is interoperable with Java. That means developers can use the Java Libraries they already use now, and the code they write with Kotlin can also be converted to Java.

Kotlin Syntax in Android

Kotlin is a concise and safe typed programming language.

I have build same an android application in Java too and we can start with this application to make comparison between Java and Kotlin.

From this two activity class, we can say that Kotlin is concise typed programming. This is because most of Java code was eliminated. Concise code takes less time to write and to read so this will improve productivity.

In Kotlin, we use colon “:” to replace words “extends” and “implements”. In this SourceActivity, we extends AppCompatActivity and implements SourceContract.View.

class SourceActivity : AppCompatActivity(), SourceContract.View

Declare Variable and Null Safety

To declare a variable in Kotlin we use keyword “val” for final variable and “var” for variable. In Kotlin we must initialize variable with a value because everything in Kotlin is not nullable. The way to declare nullable value is with the “?” question mark which also suggest you that the value could be there or not.

// implicit type
var a = 100 -> assign value
a = 30 -> reassign value
val b = 100 -> final value
b = 30 -> error, because b is final value
//explicit type
var name : String = "Eminarti" -> explicit type declare String
val age : Int = 22 -> explicit type declare Int
// nullable
var middleName : String? = null -> nullable, safe type

There are some way to interact with a nullable object. First if you don’t have problem with null value, just use “?” question mark. It will allow you to get the value just in case it exists, otherwise it will ignore it and you are safe to continue running the program. Second, if you don’t want to get a null value and throw a null pointer exception, just use “!!”.

var name : String? = null
var length = name.length -> error! name might be null
var length = name?.length -> type length nullable int
var length = name?.length ?: throw NullPointerException()
var length = name!!.length -> throw npe if name is null

Elvis Operator

This is the name used for this operator “?:”. The real reason this is great is because it handles the common scenario of “if something is null, I want to give it a value, but otherwise just return it self” or give an alternative value in case the object is null. Elvis operator looks like this

return name?.length ?: -1          -> if null, return -1

Properties and Fields

In Kotlin accessing properties like accessing a field in Java. But, instead of calling the get/set method from an Activity we directly do.

val intent = Intent(applicationContext, NewsActivity::class.java)

In Java we usually call getApplicationContext(), but in Kotlin we can use applicationContext. We can still call the getApplicationContext method but Android Studio will suggest you to change it. It doesn’t mean that you are accessing the field directly, it’s calling the getApplicationContext method but in a more convenient way. Another example:

supportActionBar                   -> from getSupportActionBar
supportActionBar.title = "Title" -> from supportActionBar.setTitle
val title = supportActionBar.title -> from supportActionBar.getTitle

Data Classes

Let’s we talk about data class. We frequently create a class to do nothing but hold data. In such a class some standard functionality is often mechanically derivable from the data. In Kotlin, this is called a data class and is marked as data. In this example, we need SourceResponse class to hold response data when we call a service from API.

@GET("sources")
fun getSources() : Call<SourceResponse>

Here is the way we make a Data Class in Java and Kotlin. Kotlin has come to help us with a new class type called “data class” which brings you a lot of benefits.

class SourceResponse(val status: String, val sources: List<Sources>)

With this simple line we are doing the same as the previous Java code, it means SourceResponse data class has two element, status and sources and they have own getter/setter and it define in constructor. We also can make an inner class with same way. And others, we still have more benefits methods that we can see in this official page.

BindingView

There are some ways to do bind view in Kotlin. Same like java we can use findViewById() for get attribute from layout file. But when using findViewById() we must define the variable with value either null based on previous statement that every field in Kotlin is object or we can use delegated properties.

// In Java using findViewById
setContentView(R.layout.activity_source);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
RecyclerView list = (RecyclerView) findViewById(R.id.list)
// In Java using ButterKnife
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.list) RecyclerView list;

setSupportActionBar(toolbar);
adapter = new SourceAdapter();
list.setLayoutManager(new GridLayoutManager(this, 2));
list.setAdapter(adapter);

Use findViewById with null initialize value

list = view?.findViewById(R.id.list) as RecyclerView?

Delegated Properties

Delegated Properties are a way to reuse common behavior that you may recurrently need for a property. Lazy delegated is a great delegated property that we are going to use to avoid initializing our list as a nullable object. With Lazy we are going to create it as a non-nullable property and will be executed just when you use it and just the first time.

private val list: RecyclerView by lazy {
view?.findViewById(R.id.list) as RecyclerView
}

Binding View with Kotlin Android Extension

In previous example of Java dan Kotlin class that I give above, there is different way to assign view and inflating the view. Usually we use findViewById or use ButterKnife for binding View. But in Kotlin we can use extensions to do it.

import kotlinx.android.synthetic.main.activity_news.*setContentView(R.layout.activity_news)
setSupportActionBar(this.toolbar)
this.list.adapter = adapter
this.list.layoutManager = LinearLayoutManager(this)

No more findViewById() that a source of potential bugs and nasty code which is hard to read and support. Before we use it, we must configuring the dependency. We’re going to be using Gradle. All you need is to enable the Android Extensions Gradle plugin in your project-local build.gradle file:

apply plugin: 'kotlin-android-extensions'

And for use it in class, we just add import and now we can use all of the member of view from layout file.

import kotlinx.android.synthetic.main.<layout>.*

Property Initialization Feature

If you do not want to initialize a property in the constructor lateinit and lazy are important property initialization feature.

lateinit is late initialization.

Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.

To handle this case, you can mark the property with the lateinit modifier.

@Inject lateinit var repository : NewsRepository

lazy is lazy initialization. Same using like delegated properties that I have mentioned above. lazy() is a function that takes a lambda and returns an instance of lazy which can serve as a delegate for implementing a lazy property: the first call to get() executes the lambda passed to lazy() and remembers the result, subsequent calls to get() simply return the remembered result.

Android Repository Pattern in Kotlin

We have learned the basic features in Kotlin that we can use it for build an Android Application. Now I will explained how to implement in Kotlin Android.

We want to build an Android Application with MVP architecture in Kotlin. Basically there is no different structure, I use a same structure folder and project both of Java and Kotlin

Structure Folder. (Left) Java and (Right) Kotlin.

Contract Class for Presenter dan View

Same like Java, here I use a contract class for define one-to-one relation between view and presenter. A Contract class usually consist of two inner interface View and Presenter and will be implement by of view and presenter. Before it, I make a base class for View and Presenter for present the general method.

And the activity and presenter class will implement view and presenter.

class SourceActivity : AppCompatActivity(), SourceContract.View {
}
class SourcePresenter(private val view : SourceContract.View,
private val repository: SourceRepository)
: SourceContract.Presenter {
}

Repository Pattern

Repository pattern in this architecture as a abstraction of data layer that will be use to manage data object in this application. This repository usually consist of interface class for list of method for data object, repository class that implement the interface, and the other class to manage the data object and implement the interface class too. This repository class will be used by presenter.

RemoteSourceDataSource.kt is a class that we used to call API. And the SourceRepository.kt use RemoteSourceDataSource.kt to get source. Sometimes we need the Local data and we can name it LocalSourceDataSource.kt. The class will be implement SourceDataSource too and this class will manage local data like communicate with database or internal storage. But in this part, I just use remote data that we got from server.

After we get the data from server and the presenter class will use this repository to bind data to view.

class SourcePresenter(val repository: SourceRepository)
: SourceContract.Presenter {

override fun getData() {
repository.getSource(
// in this block we call view for bind data
)
}

Dependency Injection

Dependency injection is a technique whereby one object supplies the dependencies of another object. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it. In this development I use Dagger 2 for dependency injection.

The example of this development is when I provide the SourceRepository class in DataModule class.

And for use the dependency we just call

@Inject lateinit var repository : SourceRepository

Conclusion

Well we’ve found that Kotlin can makes our code much better. All of Kotlin features give new experiences because of its focus on the ecosystem: JetBrains understand that productivity comes from more than convenient syntax.

Well we are ready to start developing the Android Application in Kotlin with Kotlin main features. There are so many features that I don’t covered in here because I just know a little about this language.

Here you have all the code that we are going to be creating/reviewing in this post.

Reference :
https://github.com/googlesamples/android-architecture/tree/todo-mvp/

If you have any questions or complains, please feel free to contact me in these social networks: twitter, linkedin, or email. I’ll try to do my best to answer if I can, otherwise we will learn together :).

--

--