Android Kotlin
All my android apps have up until now been written in Java, avoiding the use of the support libraries or androidx. The Google developers docs and guides advocate the use of Kotlin rather than Java and the use of androidx almost to the exclusion of the standard android API.
I have a very simple app, Oglaf, NS(Generally)FW, which is just a wrapper around the web site, with some navigation. So I decided to convert it to Kotlin, just to see how difficult it was and to see what effect, if any, it had on the app.
The obvious differences with java are declaration of variables and classes, and not needing semicolons on the end of statements.
// Java
package org.billthefarmer.oglaf;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.text.SpannableStringBuilder;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import java.text.DateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Oglaf extends Activity
{
public static final String URL = "https://oglaf.com";
public static final String TEXT_PLAIN = "text/plain";
private WebView webView;
// Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = findViewById(R.id.webview);
if (webView != null)
{
// Enable javascript, Oglaf doesn't work unless JavaScript
// is enabled
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
// Enable zoom
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
// Kotlin
package org.billthefarmer.oglaf
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.text.SpannableStringBuilder
import android.view.Menu
import android.view.MenuItem
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.TextView
import java.text.DateFormat
import java.util.regex.Matcher
import java.util.regex.Pattern
class Oglaf: Activity()
{
val URL = "https://oglaf.com"
val TEXT_PLAIN = "text/plain"
lateinit var webView: WebView
// Called when the activity is first created.
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
webView = findViewById(R.id.webview)
// Enable javascript, Oglaf doesn't work unless JavaScript
// is enabled
val settings = webView.getSettings()
settings.setJavaScriptEnabled(true)
// Enable zoom
settings.setBuiltInZoomControls(true)
settings.setDisplayZoomControls(false)
There are nuances like declaring the web view lateinit
because it is
initialised in onCreate()
.
The next bit wasn’t so easy. I had to search extensively to find the correct syntax for what Kotlin calls an object expression.
// Java
// Follow links and set title
webView.setWebViewClient(new WebViewClient()
{
// onPageFinished
@Override
public void onPageFinished(WebView view, String url)
{
// Get page title
if (view.getTitle() != null)
setTitle(view.getTitle());
if (view.canGoBack())
getActionBar().setDisplayHomeAsUpEnabled(true);
else
getActionBar().setDisplayHomeAsUpEnabled(false);
}
});
// Kotlin
// Follow links and set title
webView.setWebViewClient(object: WebViewClient()
{
// onPageFinished
override fun onPageFinished(view: WebView, url: String)
{
// Get page title
if (view.getTitle() != null)
setTitle(view.getTitle())
if (view.canGoBack())
getActionBar()?.setDisplayHomeAsUpEnabled(true)
else
getActionBar()?.setDisplayHomeAsUpEnabled(false)
}
})
The other significant difference is that a case statement becomes a when statement.
// Java
// Get id
int id = item.getItemId();
switch (id)
{
// Home
case android.R.id.home:
// Back navigation
if (webView != null && webView.canGoBack())
webView.goBack();
else
finish();
break;
// Refresh
case R.id.action_refresh:
refresh();
break;
// Share
case R.id.action_share:
share();
break;
// About
case R.id.action_about:
about();
break;
default:
return false;
}
// Kotlin
// Get id
val id = item.getItemId()
when (id)
{
// Home
android.R.id.home ->
// Back navigation
if (webView.canGoBack())
webView.goBack()
else
finish()
// Refresh
R.id.action_refresh ->
refresh()
// Share
R.id.action_share ->
share()
// About
R.id.action_about ->
about()
else ->
return false
}
The obvious difference with the app is that the Java version size is 74Kb, the Kotlin version is 781Kb. Rather a lot of bloat for a small simple app.