Modern Android development with Kotlin

Modern Android development with Kotlin
Kotlin promises a well-readable and concise syntax, modern language features and functional programming with high security. Does the Java alternative, thanks to its seamless interaction with Android, make the hearts of app developers beat faster?

After five years of development, JetBrains launched the long-awaited version of Kotlin 1.0 in February 2016 and promised stability: Future Kotlin versions are no longer required for existing code. As a statically typed general-purpose language for JVM and browsers, Kotlin can be used wherever Java is running.



The following extended "Hello World" demonstrates a first impression of the concise spelling and at the same time good readability. Even without prior experience the example would be understandable to most Java developers.

[success title="Code" icon="check-circle"] import java.util.*

fun main(args: Array<String>) {
    val name = if (args.size > 0) args[0] else "Publikum"
    val zuschauer = Gast(name, title = Title.wertes)

    println(zuschauer)
    println("Hallo ${zuschauer.title} $name")
}

data class Gast(val name: String,
                var zeit: Date = Date(),
                val title: Title?)
enum class Title { Herr, Frau, wertes } [/success]

The example shows some properties that make working with Kotlin efficient. This includes the concise keywords and optional semicolons at the end of the line or the use of expressions in string templates. Parameters can have default values and thus become optional.

As a statically and strictly typed language Kotlin offers the well-known good security, but saves the developer unnecessary typing. Thanks to Type Inference, local variables, in particular, open their type themselves, so that type specifications are usually only necessary at interfaces.

The Data class Guest is a simple, extensible value container. Kotlin takes much of the classic boilerplate code, such as getter and setter methods, null value checks, equals (), hashCode (), and toString () implementations, as well as individual convenience functions. Data Classes can be decomposed easily into their individual properties.
[success title="Code" icon="check-circle"] var (zname, _, ztitel) = zuschauer[/success]
The functionally equivalent Java implementation of the three-line DataClass guest, however, puts it on stately 100 lines.

The fact that the Kotlin code, despite its brevity, is nevertheless well and intuitively readable, becomes clear in practice by the short training period. A lot of basic knowledge and the desire for more elegant code is often enough for experienced Java developers to open up a large part of the Kotlin functions, using compilers and IDEs.

Where intuition no longer suffices, a glance into the successful documentation helps. Kotlin Koans is suitable for the first steps or further study. This curriculum of 42 learning units can be worked out directly in the browser or with the "Kotlin Koans" plug-in in the free IntelliJ IDE (unfortunately not in Android Studio).

Android development with Kotlin
When it comes to Kotlin in the context of the Android development, the language is certainly characterized by its interoperability. Despite the many advanced language features, Kotlin is content with Java 6 bytecode and, unlike Java 8, is unrestrictedly compatible with all Android versions.
In the project, Java and Kotlin libraries as well as individual classes of the source code can be freely mixed in both languages and can access each other without restrictions. By means of a conversion function in Android Studio, developer projects can gradually migrate to Kotlin and thus experience a direct comparison. The seamless access in both directions emphasizes Kotlin clearly from other JVM languages.
From the same house as Kotlin, IntelliJ IDEA also comes from. The IDE forms the basis for Google's official development environment Android Studio. In addition, Androids builds system Gradle from version 3 on Kotlin as an additional possibility for the build definitions. Both of these promises excellent tooling integration and future-proofing.
The introduction to the app development with Kotlin succeeded very easily. Under File | Settings | Plugins can be installed Kotlin via caps] Install JetBrains plugin [/ caps] in Android Studio. A reboot later the key combination Ctrl + Shift + A offers the action Configure Kotlin in Project under the keyword Kotlin. And developers can already use Kotlin in the project. A more detailed guide can be found in the official step-by-step guide.

Using the Convert Java File to Kotlin File action, individual Java classes can now be automatically transferred to Kotlin. In more complex classes manual rework is occasionally required to a small extent. As a rule, these are due to strict zero-value treatment in Kotlin.
Security, Properties & UI Access

In the type system of Kotlin, zero has a place of honor opposite that of Java: Kotlin types know whether they can contain null values. Compiler and IDE require stringent consideration of the interface contract. For example, TextView always guarantees a value, while ViewGroup? can also have zero values and thus has to be treated specifically in the control flow as well as in the case of deregulation:
[success title="Code" icon="check-circle"] var toolbar: ViewGroup? = null
var textView: TextView = TextView(baseContext)[/success]
Therefore, unchecked accesses or assignments with null-enabled types as in the following examples are not allowed and generate compiler errors. At interfaces to Java, Kotlin also makes transparent checks or passes on his knowledge of @ NotNull annotations.
[success title="Code" icon="check-circle"] // Alle Statements erzeugen Compiler-Fehler
toolbar.measuredHeight
textView = toolbar.getChildAt(0) as TextView[/success]
The treatment of zero values sweetened Kotlin with many abbreviations. Under Java the following code would be necessary for the requested checks:

[success title="Code" icon="check-circle"]TextView child = null;
if (toolbar != null && toolbar.getChildAt(0) instanceof TextView) {
    child = (TextView) toolbar.getChildAt(0);
}
textView = child != null ? child : new TextView(getBaseContext());

if (textView instanceof EditText) {
    ((EditText) textView).selectAll();
}[/success]
The Elvis operator (?) And the Safe-Call operator (?.) Are shorthand styles known from other programming languages. A special feature of Kotlin, however, is that it takes into account preexisting type tests using the so-called SmartCast. In the example, the compiler understands that inside the if block, textView must be of the EditView type and preserves the developer from a new null-value check or an explicit type-conversion. Despite the additionally requested security, the variant with Kotlin reads clearly more elegant and more concise than the original.
[success title="Code" icon="check-circle"]val child = toolbar?.getChildAt(0) as? TextView
textView = child ?: TextView(baseContext)

if (textView is EditText) {
    textView.selectAll()
}[/success]

Properties
Noteworthy readers will not have noticed that the call getBaseContext () in cotlin has become a simple baseContext. Classes in Kotlin can have properties that implicitly contain getter methods and, if necessary, additional setters. Both can be overloaded. As with variables, variable properties are defined by the var keyword, while only readable properties are declared val. When accessing Java code, Kotlin makes suitable getter / setter pairs appear as properties, which explains the abbreviation mentioned at the outset.

Access to UI elements
In the context of Android Kotlins Properties bring along some other interesting features. The synthetic properties of the Kotlin Android Extensions offer a true productivity boost. One of the biggest sources of Boilerplate code on Android is likely to be familiar to developers: the continuous recurring pattern for accessing the views in the Activities or Fragments using the findViewById () method.
[success title="Code" icon="check-circle"]EditText editTitle = (EditText) v.findViewById(R.id.edit_title);
editTitle.setText(mItem.getTitle());

CheckBox enabledBox = (CheckBox) v.findViewById(R.id.enable_box);
enabledBox.setChecked(true);

Button createButton = (Button) v.findViewById(R.id.create_entry);
createButton.setOnClickListener(new OnClickListener() {
    @Override public void onClick(View button) {
        createElement();
    }
});[/success]
The Butter-Knife library also provides Java approaches to save parts of this typing work. Kotlin goes one step further, and makes working with UI elements under Android almost completely transparent. The Kotlin Android Extensions provided by the company automatically generate correctly typed properties in a synthetic package for compile time for all UI widgets of a layout. This reduces access to GUI elements to an import statement and their direct use as objects via their IDs.
[success title="Code" icon="check-circle"]import kotlinx.android.synthetic.main.activity_hello.*
// ...
edit_title.setText(mItem.title)
enable_box.isChecked = true
create_entry.setOnClickListener { createElement() }[/success]
To get this icing on the cake, it is enough to add the additional apply plugin: 'kotlin-android-extensions' directive to app / build.gradle. Afterwards, a virtual package of the same name can be imported for each layout file.

In the example, the kotlinx.android.synthetic.main.activity_hello package provides access to all the UI elements defined in the layout / activity_hello.xml file. Since the virtual properties already have the correct type, a further annoying source of errors can be eliminated with the otherwise required typecasts.
Delayed initialization and delegation
Often values under Android are not yet known when the class is created and are available only on the onCreate () callback. The declaration of so-called lateritic properties allows to initialize properties outside the constructor. Thus, the program does not have to resort to null values, which would require a full zero-value treatment on each access.

Also the powerful option to delegate access to properties via by to third parties offers further approaches. In the example, the initialization of the imm property as a lambda expression is delegated to lazy () and thus to the first read access.
[success title="Code" icon="check-circle"]val lateinit id: String
val imm: InputMethodManager by lazy ( {
    getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager } )

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  id = getString(R.string.app_name)
  imm.showInputMethodPicker()
}[/success]

For all the advantages - a small potential horsefoot for Android, however, the Kotlin properties have: Because additional attributes for getter and setters are to be generated for public attributes, the 64k method limit of the Android DEX files is faster. If necessary, developers can avoid this with latinit or @JvmField.
Extension Methods, Functions & Example
Extension Methods and Properties
The APIs of Android and Java are designed for a wide range of applications and maximum flexibility. In everyday life this is often reflected in long and repetitive uses. In your own Android app, developers are looking for fast, individual shortcuts for recurring paths. Usually, this leads quickly to a potpourri of different Util classes in the project.

To avoid this, Kotlin, similar to C #, allows the extension of foreign classes to have new functionality without having to derive them or to package them into a decorator pattern. Extensions Methods and Extension Properties can be used to extend Java and Android classes with new methods and properties.
[success title="Code" icon="check-circle"]fun Fragment.toast(msg: String,
                   dur: Int = Toast.LENGTH_SHORT) {
  Toast.makeText(this.getActivity(), msg, dur).show()
}

var EditText.stringValue: String
    get() = text.toString()
    set(str) { setText(str)  }

val Int.dpInPixel: Int get() = (
      this * Resources.getSystem().displayMetrics.density + 0.5f
    ).toInt()[/success]
The example expands the Android Fragments by adding a method for toast messages, the EditText widgets by a property for more comfortable direct access to the current text, and integer numbers by a property for direct conversion of a dp unit into pixels. Their use is similar to elegant:
[success title="Code" icon="check-circle"]toast("Hallo!")
nameEdit.stringValue = "Unbekannter"
val p = 5.dpInPixel[/success]
Already Kotlin's standard library provides extensions to Java classes. Besides own extensions, libraries such as KAndroid and Anko, which are aimed specifically at Android, offer further helpful extensions.
Functions as language elements
Functions to create events is part of the daily bread of app developers. The necessary code in the traditional form under Android still somewhat bulky.
[success title="Code" icon="check-circle"]view.setOnClickListener(new OnClickListener() {
    @Override public void onClick(View view) {
        view.scrollTo(0,0);
    }
});[/success]
In recent Android versions or with Retrolambda, the anonymous function expressions known as lambda or closure can be used to implement interfaces with only one missing method (single abstract method). The approach also follows cotlin, so the click listener can be implemented in the following form:
[success title="Code" icon="check-circle"]view.setOnClickListener { it.scrollTo(0,0) }[/success]
The symbol it is a built-in placeholder in Kotlin. It can always be used if the function expression expects only one parameter. For functions with several parameters the presumably somewhat more familiar syntax {x, y -> x + y} is used. If a lambda expression is the last parameter of a function call, the parentheses can be omitted. The previous example is, therefore, only syntactic sugars for the expelled form under Kotlin:
[success title="Code" icon="check-circle"]view.setOnClickListener ({ view -> view.scrollTo(0,0) })[/success]
However, Kotlin goes beyond the lambdas known from Java 8, since functions in the language are elements of the first class. They can be used as variables, properties, parameters and return values. This allows interleaving of functional expressions, generally known as higher order functions.
The following function expects a different function as a parameter and executes it only if the current Android version is at least nougat:
[success title="Code" icon="check-circle"]fun ifNougatOrNewer(f: () -> Unit) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    f()
  }
}[/success]
It can be used without round brackets thanks to the short-cut notes.
[success title="Code" icon="check-circle"]ifNougatOrNewer {
  showVRButton()
}[/success]
A large part of the Kotlin Standard Library supplements the existing Java classes with extensions by higher-order functions. They often retrofit advanced, but commonly used functions like filter ().
[success title="Code" icon="check-circle"]val list = listOf("a", "b", "c", "d")
for (index in list.indices.filter { it % 2 == 0 }) {
    println("$index -> ${list[index]}")
}[/success]
Example App
Finally, a small example of a practical impression. Except for the layout XML, easily created in the layout editor, it is a completely Android app written in Kotlin. New is the when expression as a flexible replacement for the switch operator. Apart from constant values, developers can also use expressions (isValid (id)), ranges (in 3..7), or type tests (is String).

[success title="Code" icon="check-circle"]package com.kalitut.helloworld

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.EditText
import kotlinx.android.synthetic.main.activity_hello.*
import java.util.*

class HelloActivity : AppCompatActivity() {

    private val gast = Gast(name = "Publikum")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_hello)
        modelToView()

        editName.setOnEditorActionListener { v, i, e ->
            gast.name = editName.inhalt()
            modelToView()
            false
        }
        anredeGroup.setOnCheckedChangeListener({ g, id ->
            gast.titel = when (id) {
                radioHerr.id -> Titel.Herr
                radioFrau.id -> Titel.Frau
                else -> Titel.wertes
            }
            modelToView()
        })
    }

    fun modelToView() {
        labelGruss.text = gast.anrede
    }
}

enum class Titel { wertes, Herr, Frau, Doktor }

data class Gast(var titel: Titel = Titel.wertes,
                var name: String, val geburt: Date? = null) {
    val anrede: String
        get() = "Hallo $titel $name!"
}

fun EditText.inhalt(): String = text.toString()[/success]
Modern Android development with Kotlin
Conclusion
A closer look at Kotlin as an alternative for the Android development is worthwhile. In addition to the added security and conciseness, the programming language, which is well integrated into Android Studio, attracts many improvements and new expressions that developers do not want to miss in everyday life. Although the present article has only a first overview and there is much more to be discovered, Kotlin code is always easy to read and easily understandable.
The small helpers, in particular, have a surprisingly pleasant effect on the development efficiency. Besides the comfortable access to UI widgets via the Kotlin Android Extensions, the standard library brings a lot of new comfort. The often only one-line extensions of the 736 KByte slim runtime facilitate many everyday tasks and make individual utility libraries superfluous.
The higher order functions of the Kotlin standard library are marked for in-line compilation, so their use in practice does not involve any additional overhead against a manual, sequential implementation. This is especially interesting for Android, but it allows the expressiveness of scale-like constructs, without having to accept the otherwise usual losses during the runtime. With Kovenant, Kndroid, Anko and Fuel, the Kotlin ecosystem has other interesting libraries to offer especially for Android developers.
The combination of Kotlin and Android now leaves a coherent and mature impression and is not least due to the seamless interaction with Java code an attractive overall package. Wherever it is, the author likes to go to Kotlin and invites him to do the same in his own experiments. Happy Koding!

Benjamin Schmid
as a Technology Advisor, advises his colleagues at eXXcellent solutions GmbH in all technological and methodological questions. His hands-on experience and aha-moments around Java, Web and .NET, he always likes to pass on.

Modern Android development with Kotlin Kotlin promises a well-readable and concise syntax, modern language features and functional programming with high security

Labels:

Post a Comment

[blogger]

Author Name

{picture#YOUR_PROFILE_PICTURE_URL} YOUR_PROFILE_DESCRIPTION {facebook#https://www.facebook.com/wTsXDev} {twitter#https://twitter.com/wTsDev} {google#https://plus.google.com/u/0/+AnonSalame} {pinterest#https://www.pinterest.com/Thexwts/} {youtube#https://www.youtube.com/channel/UCg2fUa8Yp-aWDCJYQTVHmBg}

Contact Form

Name

Email *

Message *

Powered by Blogger.