Kotlin


First created: Tuesday 29th September 2020, 11:13 PT, AD
Last updated: Sunday 25th October 2020, 11:26 PT, AD

Android app development using Kotlin

on Ubuntu Linux 18.04 LTS OS
with Android Studio 4.0.2 (September 2020).

Anne Dawson

Hardware requirements: computer system requirements

Reference Textbooks:

https://kotlinlang.org/docs/books.html

https://kotlinandroidbook.com/


Learn Android Studio 3 with Kotlin: Efficient Android App Development 
1st ed. Edition, by Ted Hagos 

Source Code (with link to book)

Head First Kotlin by Dawn Griffiths and David Griffiths

Source code: Gitlab


Introduction

 
Why Kotlin?

The current popularity of Kotlin and Android Studio

Software requirements: all open source (free)

Learn Android Studio 3 with Kotlin

 
Learn Android Studio 3 with Kotlin: Efficient Android App Development 
1st ed. Edition, by Ted Hagos 

Source Code (with link to book)

Part 1 - The Kotlin Language
Chapter 1 - Getting into Kotlin (Finished Thursday 15th Oct 2020)
Chapter 2 - Kotlin Basics (Finished Friday 16th Oct 2020)
Chapter 3 - Functions (Finished Friday 16th Oct 2020)
Chapter 4 - Working with Types (Finished Thursday 22nd Oct 2020)
Chapter 5 - Lambdas and Higher Order Functions (up to p108 Friday 23rd Oct 2020)
Chapter 6 - Collections and Arrays
Chapter 7 - Generics
Part 2 - Android Programming with Kotlin
Chapter 8 - Android Studio Introduction and Setup  
Android Studio
GitHub 
Chapter 9 - Getting Started
Debugging in Android Studio
Chapter 10 - Activities and Layouts  
Android UI Layouts
Chapter 11 - Event Handling 
Chapter 12 - Intents 
Chapter 13 - Themes and Menus 
Chapter 14 - Fragments 
Chapter 15 - Running in the Background 
Chapter 16 - Debugging 
Chapter 17 - SharedPreferences 
Chapter 18 - Internal Storage 
Chapter 19 - BroadcastReceivers 
Chapter 20 - App Distribution 

Android
Android Studio
Android UI Layouts
Android Courses 
Debugging in Android Studio
GitHub
Idiomatic Programming 
References
Further Reading








Chapter 1 - Getting into Kotlin


Kotlin code is shorter and easier to understand compared to a language like C++ or Java. 
The new Kotlin features shorten the project development time 
and reduce the number of runtime errors, 
which in turn reduces the number of app crashes. 
Android Jetpack will be used to reduce UI development time.

Kotlin is installed with the IntelliJ IDEA Community Edition integrated development environment. 
If you're installing on a Linux machine, 
you may use the Ubuntu Software app for installation,
then follow these instructions to create a Kotlin project to make a Kotlin application.

Movie 1: Hello World!

Movie 2: How to make a Kotlin Application using IntelliJ IDEA. Under development.

FYI - For setting up the project build type

FYI - What the different folder colours mean in an IntelliJ Idea Project

Working with the Command Line Compiler

Github - "Hello World!"





Chapter 1 - Getting Started with Kotlin - BULLET POINTS

Use fun to define a function.

Every application needs a function named main.

Use // to denote a single-lined comment.

A String is a string of characters. You denote a String value by
enclosing its characters in double quotes.

Code blocks are defined by a pair of curly braces { }.

The assignment operator is one equals sign =.

The equals operator uses two equals signs ==.

Use var to define a variable whose value may change.

Use val to define a value whose value will stay the same.

A while loop runs everything within its block so long as the
conditional test is true.

If the conditional test is false, the while loop code block won’t run,
and execution will move down to the code immediately after the
loop block.

Put a conditional test inside parentheses ( ).

Add conditional branches to your code using if and else. 
The else clause is optional. 

You can use "if" as an expression so that it returns a value. 
In this case, the else clause is mandatory.


REPL (Read-Eval-Print-Loop) is a tool for running Kotlin code interactively. 
REPL lets you evaluate expressions and code chunks without creating projects 
or even functions if you don't need them.

To run REPL in IntelliJ IDEA, open Tools | Kotlin | Kotlin REPL.

Kotlin keywords,operators and special symbols

Chapter 1 code (HFK)

Chapter 1 - Getting into Kotlin - Summary
• Kotlin is the newest programming language for Android, and it has
first-class support on Android Studio 3.
• There are many ways to install the Kotlin command line compiler and
runtime on macOS, Linux, and Windows.
• Various IDEs have support for the Kotlin language; on some of them,
you’ll have to get a plug-in, and on some, it’s supported out of the
box.
• Kotlin looks similar to Java, but it also has differences.
• IntelliJ has excellent support for Kotlin—well, JetBrains created
Kotlin after all.









Chapter 2 - Kotlin Basics



Assignments

Assignments are statements in Kotlin but they are expressions in Java.

A variable in Kotlin is
created by declaring an identifier using the var keyword followed by the type, like in the
statement


var foo: Int
var foo: Int = 10
var foo = 10  // type inference



Variables, Expressions and Statements

Variables declared with the val keyword 
can be initialized only once within the 
execution block where they were defined. 
That makes them effectively constants.
Think of val as the equivalent of the 
final keyword in Java - 
once you initialize it to a value, 
you can’t change it anymore, they’re immutable. 

While variables that were created using var are mutable,
they can be changed as many times as you want.

An expression is a combination of operators, functions, 
literal values, variables, or constants 
and always resolves to a value. 
It also can be part of a more complex expression. 
A statement can contain expressions, but in itself, 
a statement doesn’t resolve to a value. 
It cannot be part of other statements. 
It’s always a top-level element in its enclosing block.

Assignments are expressions in Java, 
but they are statements in Kotlin.

Another notable difference between Kotlin and Java 
when it comes to expressions and statements 
is that in Kotlin, most control structures 
(except for, do, and do/while)
are evaluated expressions, 
while in Java they are statements.



Keywords

Kotlin has hard, soft, and modifier keywords. 
The hard keywords are always interpreted as keywords 
and cannot really be used as identifiers. Some examples of these
are as, break, class, continue, do, else, false, 
while, this, throw, try, super, and when.

Soft keywords act as reserved words in certain context
where they are applicable; otherwise, they can be used 
as a regular identifier. Some examples of soft keywords
are the following: file, finally, get, import, receiver, 
set, constructor, delegate, get, by, and where.

Finally, there are modifier keywords. These things act 
as reserved words in modifier lists of declarations; 
otherwise, they can be used as identifiers. 
Some examples of these things are the following: 
abstract, actual, annotation, companion, enum, final,
infix, inline, lateinit, operator, and open.



Operators

==, != These are equality operators. 
Since Kotlin doesn’t have primitive types (like in Java), 
you can use these operators to compare any type, basic or otherwise:


var a = "Hello"
var b = "Hello"
if (a == b) // this evaluates to true


Kotlin translates this internally to call to .equals() method.

Referential equality is checked by the === operation 
(and its negated counterpart !==). 
a === b evaluates to true if and only if a and b point to the same object. 
For example,


var p1 = Person("John")
var p2 = Person("John")
if(p1 === p2) { // false
println("p1 == p2")
}





Comments

//   or multiline   /*   */
and:

KDoc is like Javadoc, it starts with /** and it ends with */. This
form of commenting is very similar to the multiline comment
(above), but this is used to provide API documentation to Kotlin
codes. Listing 2-4 illustrates how to use the KDoc syntax.
Listing 2-4. KDoc Syntax


/**
This is an example documentation using KDoc syntax

@author Ted Hagos
@constructor
*/
class Person(val name: String) {
    /**
    This is another KDoc comment
    @return
    */

    fun foo(): Int{
    }
}




Strings

Much of what we’ve learned about Java Strings 
are still applicable in Kotlin; hence, this
section will be short.
The easiest way to create a String 
is to use the escaped string literal—escaped strings
are actually the kind of strings we know from Java. 
These strings may contain escape characters like \n, 
\t, \b, etc. See the code snippet below.


var str: String = "Hello World\n"


Kotlin has another kind of string that is called a raw string.
A raw string is created by using triple quote delimiter. 
They may not contain escape sequences, but they can
contain new lines, like


var rawStr = """Amy Pond, there's something you'd
better understand about me 'cause it's important,
and one day your life may depend on it:
I am definitely a mad man with a box!
"""





The if expression

The new thing about Kotlin’s "if" is that it’s an expression, 
which means we can do things like 
 

val theQuestion = "Doctor who"
val answer = "Theta Sigma"
val correctAnswer = ""
var message = if (answer == correctAnswer) {
	"You are correct"
}
else{
    "Try again"
}


The String on the first block of the if construct will be returned 
to the message variable if the condition is true; otherwise, 
the String on the second block will be the returned value. 
We can even omit the curly braces on the blocks, 
since the blocks contain only single statements.

var message = if (answer == correctAnswer) "You are correct" else "Try again"

The code example above would probably remind you 
of the ternary operator in Java.
By the way, Kotlin doesn’t support the ternary operator, 
but don’t worry since you don’t need it. 
The if construct is an expression, 
if you feel you need to write code that requires
the ternary operator, just follow the preceding code example.



The when Statement

Kotlin doesn’t have a switch statement, but it has the when construct. 
Its form and structure is strikingly similar to the switch statement. 
In its simplest form, it can be implemented like this:


val d = Date()
val c = Calendar.getInstance()
val day = c.get(Calendar.DAY_OF_WEEK)
when (day) {
   1 -> println("Sunday")
   2 -> println("Monday")
   3 -> println("Tuesday")
   4 -> println("Wednesday")
}


The when construct can also be used as an expression, 
and when it’s used as such, each branch becomes 
the returned value of the expression. See the code example:


val d = Date()
val c = Calendar.getInstance()
val day = c.get(Calendar.DAY_OF_WEEK)
var dayOfweek = when (day) {
   1 -> "Sunday"
   2 -> "Monday"
   3 -> "Tuesday"
   4 -> "Wednesday"
   else -> "Unknown"
}


Just remember to include the else clause when when is used as an expression. 
The compiler thoroughly checks all possible pathways 
and it needs to be exhaustive, which is
why the else clause becomes a requirement.




The for loop

Listing 2-11. Using Ranges in for Loop



for (i in 1..10) {
println(i)
}





Exception Handling

Kotlin’s exception handling is very similar to Java: 
it also uses the try-catch-­finally construct. 
Whatever we’ve learned about Java’s exception handling 
commutes nicely to Kotlin. 
However, Kotlin simplifies exception handling 
by simply using unchecked exceptions. 
What that means is writing try-catch blocks is now optional.

Listing 2-14. Demonstration of Nullable Types


fun main(args: Array<String>) {
   var a = arrayOf(1,2,3)
   printArr(null)
}
fun printArr(arr: Array<Int>?) {  
   if(arr != null) {  
      arr.forEach { i -> println(i) }  
   }
}




The safe-call operator

Kotlin introduced an operator that we can use to handle Nullable types. 
It’s called the safe-call operator, which is written as 
the question mark symbol followed by a dot ?.
We can replace the entire if block, which performs the null checking, 
with just one statement:

arr?.forEach { i -> println(i) } 

What the safe call does is to first check if arr is null; 
if it is, it won’t go through the forEach operation. 
Only when arr is not null will the array be traversed.



Random numbers

Get a random number between 0 and 2:  (p115 HFK)

val rand1 = (Math.random() * 3).toInt()

Note: Math.random() gets a (Float or Double?) random number between 0 and almost 1.
Float and Double types may call the .toInt() method 
to chop off the fractional part leaving an integer either 0, 1 or 2 in this case.


Chapter 2 - Data Types BULLET POINTS

In order to create a variable, the compiler needs to know its name,
its type, and whether it can be reused.

If the variable’s type isn’t explicitly defined, the compiler infers it
from its value.

A variable holds a reference to an object.

An object has state and behavior. Its behavior is exposed through its
functions.

Defining the variable with var means the variable’s object reference
can be replaced. Defining the variable with val means the variable
holds a reference to the same object forever.

Kotlin has a number of basic types: Byte, Short, Int, Long, Float,
Double, Boolean, Char and String.

Explicitly define a variable’s type by putting a colon after the
variable’s name, followed by the type:
var tinyNum: Byte

You can only assign a value to a variable that has a compatible type.

You can convert one numeric type to another. If the value won’t fit
into the new type, some precision is lost.

Create an array using the arrayOf function: 
var myArray = arrayOf(1, 2, 3)

Access an array’s items using, for example, myArray[0]. The first
item in an array has an index of 0.

Get an array’s size using myArray.size.

The compiler infers the array’s type from its items. You can
explicitly define an array’s type like this:
var myArray: Array<Byte>

If you define an array using val, you can still update the items in
the array.

String templates provide a quick and easy way of referring to a
variable or evaluating an expression from inside a String.

GitHub

Debugging your first Kotlin application









Chapter 3 - Functions


Kotlin’s functions are almost the same as Java methods, 
although it’s closer in behavior to functions in JavaScript, 
because in Kotlin, functions are more than just a named collection of statements. 
In Kotlin, functions are first-class citizens; you can use
a function wherever you could use a variable. 
You can pass them as parameters to other
functions, and you can return functions from other functions as well.


Declaring Functions

Functions can be written in three places. 
You can write them 
(1) inside a class, like
methods in Java—these are called member functions; 
(2) outside classes—these are
called top-level functions; and 
(3) they can be written inside other functions—these 
are called local functions. 

Regardless of where you put the function, the mechanics of
declaring it doesn’t change much. 
The basic form a function is as follows:


fun functionName([parameters]) [:type] {
  statements
} 

Listing 3-2. displayMessage With an Explicit Return Type


fun displayMessage(msg: String, count: Int) : Unit {
  var counter = 1
  while(counter++ <= count ) {
    println(msg)
  }
}


See ch3-display-message.kt



The Unit return type corresponds to Java’s void.

You can return anything from functions; 
we’re not limited to the basic types.




Single Expression Functions

Earlier in the chapter, we did say that functions follow the basic form


fun functionName([parameters]) [:type] {
  statements
}


There is a second form of writing functions in Kotlin 
that allows for a more concise syntax. 
There are situations when we can omit: 
(1) the return statement; (2) curly braces;
and (3) the return type altogether. 
This second form is called single expression functions.
As you may have inferred from its name, 
the function only contains a single expression,
as shown in the code snippet here:


fun sumInt(a: Int, b: Int) = a + b


A single expression function omits the pair of curly braces 
and instead uses an assignment operator in its place. 
It also doesn’t need the return statement anymore
because the expression on the right-hand side 
of the assignment automatically becomes the returned value. 

Finally, a function like this doesn’t need an explicit return type
because the compiler can infer the type that’s returned from the value of expression. 
The omission of the explicit return type is not in any way a hard rule. 
You may still write an explicit return if that’s what you prefer, like so:


fun sumInt (a: Int, b: Int): Int = a + b




Default Arguments

Function parameters can have default values in Kotlin, 
which allows the caller (of the function) 
to omit some arguments on the call site. 
A default value can be added to function’s signature 
by assigning a value to a function’s parameter. 
An example of such a function is shown in Listing 3-7.

Listing 3-7. connectToDb


fun connectToDb(hostname: String = "localhost",
                username: String = "mysql",
                password:String = "secret") {
}


Kotlin’s ability to provide default arguments 
to functions allows us to avoid creating function overloads. 
We couldn’t do this in Java, which is why we had to resort to method
overloading. Overloading functions is still possible in Kotlin, 
but we’ll probably have fewer reasons to do that now, 
all thanks to default parameters.


Variable Number of Arguments

Functions in Kotlin, like in Java, 
can also accept an arbitrary number of arguments. 
The syntax is a bit different from Java, 
instead of using three dots after the type ... , 
we use the vararg keyword instead.

See CH3-vararg.kt

Extension Functions

In Java, if we needed to add functionality to a class, 
we could either add methods to the class itself or extend it by inheritance. 
An extension function in Kotlin allows us to add behavior to an existing class, 
including the ones written in Java, without using inheritance.

Listing 3-12. Extended String Class


fun main(args: Array<String>) {
  val msg = "My name is Maximus Decimus Meridius"
  println(msg.homerify())
  println(msg.chanthofy())
  println(msg.terminatorify())
}
fun String.homerify() = "$this -- woohoo!"
fun String.chanthofy() = "Chan, $this , tho"
fun String.terminatorify() = "$this -- I'll be back"


It’s perfectly alright to still write utility functions in Kotlin, 
but with extension functions at our disposal, 
it seems more natural to use them because it increases the
semantic value of our code. 
It feels more natural to use extension function syntax.

CH3-extensionFunctions.kt


Infix Functions

Listing 3-14. Person Class With an infix Function


fun main(args: Array<String>) {
  val john = Person("John Doe")
  john say "Hello World"
}
class Person(val name : String) {
  infix fun say(message: String) = println("$name is saying $message")
}



Infix functions and Infix operators let us increase the semantic values
of our codes by allowing to us write function invocations without
using the dot notation. By allowing function calls to be infix-ed, the
resulting code becomes more expressive and closer to the language
of the domain.


See CH3-infixFunctions.kt

See CH3-infixOperator.kt





Chapter 4 - Working with Types


Kotlin, like Java, is a class-based, object-oriented language. 
It uses interfaces and classes to define custom types.

Interfaces

Listing 4-1. Interface Fax


interface Fax {
  fun call(number: String) = println("Calling $number")
  fun print(doc: String) = println("Fax:Printing $doc")
  fun answer()
}


It still uses the interface keyword, and it also contains abstract function(s). 
What’s remarkable about Kotlin interfaces are that they can:
(1) contain properties and (2) have functions with implementations
- in other words, concrete functions.

To implement an interface, Kotlin uses the colon operator, 
as shown in Listing 4-2.

Listing 4-2. class MultiFunction Implementing Fax 


class MultiFunction : Fax {  
  override fun answer () {  
  }
}


Invoking Super Behavior

To invoke a function on a supertype, you’ll need three things: 
(1) the super keyword; 
(2) name of the supertype enclosed in a pair of angle brackets; and 
(3) the name of function you want to invoke on the supertype. 

It looks something like the code snippet here:


super<NameOfSuperType>.functionName()


See project: CH04Interfaces
CH4-interface.kt



Classes

kotlin.org doc on classes

Listing 4-8. A basic class in Kotlin


class Person() {
}


The header of the class is the pair of parentheses. The header may contain
parameters, but in this example, it doesn’t have any. The pair of curly braces comprises
the body of the class. Both the header and the class body are optional, but most of the
codes we will use this in book will include both of them.
To instantiate the Person class, we can write something like the following:

var person = Person()

If not for the noticeable absence of the new keyword, it looks a lot like how we would
create objects in Java. The pair of parentheses after the type name (Person) is a call to a
no-arg constructor. Let’s go back a bit to Listing 4-8 and take a closer look at the
header portion of the class definition. This is one of the few areas where Kotlin looks
and feels a bit different from Java. Java classes didn’t have headers, but Kotlin does. This
header is actually a constructor definition.

When the primary constructor doesn’t have (or need) annotations or visibility modifiers, we
can omit the constructor keyword, like so:

class Person (_name: String) {
  var name:String
  init {
    name = _name
  }
}


We can further simplify and shorten the code by joining the init block and
declaration of the name variable in a statement. Kotlin is smart like that.


class Person (_name: String) {
  var name:String = _name
}

Constructors may also be defined inside the body of the class, just like the way it
was done in Java. When they are written as such, they are called secondary constructors.
Listing 4-10 shows a sample code with a secondary constructor.


Listing 4-10. Employee Class, with Secondary Constructor

class Employee {
  var name:String
  constructor(_name: String) {
    name = _name
  }
}


Notice in Listing 4-11 that we didn’t have to use the init block because the
initialization of the name member variable was done in constructor body. A secondary
constructor, unlike a primary constructor, can contain code. A secondary constructor needs to have the constructor keyword.

See: CH4-classes.kt

See: CH4-constructors.kt



Inheritance

Kotlin classes are final by default, as opposed to Java classes that are "open" or non-final. 
Kotlin classes and their functions are final by default. 
To allow a class to be extended it must be marked open (or interface to be implemented),
meaning that it's "open to be extended". To allow class functions and fields to be
overridden, they must also be marked as open. The root of the Kotlin class hierarchy -
every Kotlin class has Any as a superclass.


See: CH4-inheritance.kt




Properties

A property in a class or object is traditionally created by defining a member variable
and providing accessor methods for it. These methods will usually follow some naming
conventions where the name of the member variable will be prefixed by get and set.

In the following code, name is basically a property of the class Customer. 
It has an internal backing field and a getter and a setter method 
already associated with it, which can be overridden if you wish: 


class Customer {
  var name = "John"
    get() = name.toUpperCase();
    set(value) {
      field = value.toUpperCase()
    }
  ...
}





Listing 4-20. Simplified Person class


class Person(val name:String)
fun main(args: Array<String>) {
  var person = Person("John Smith")
  println(person.name)
}


The code here is the most concise way of defining a property in Kotlin. 
It’s also considered idiomatic. Notice the changes we made in the code:
1. The parameter in the primary constructor now has a val
declaration. This effectively makes the constructor parameter a
property. We could have used var, and it would work just as well.
2. We no longer need to differentiate the identifier in the constructor
parameter with the member variable; hence we dropped the
leading underscore in the _name variable.
3. We can drop the entire body of the class since we don’t need
it anymore. The class body only contains the code to transfer
the value of the constructor parameter to the member variable.
Since Kotlin will automatically define a backing field for the
constructor parameter, we don’t have to do anything anymore in
the class body. The code in Listing 4-20 shows the most basic way 
to define data objects in Kotlin.

By simply using
either val or var in the primary constructor parameters, we can automagically define
properties with proper mutator methods. However, there will still be situations when
you will need to exercise more control over the “getting” and “setting” process of these
properties. Kotlin allows us to do that as well.
We can take over the automatic process of “getting” and “setting” by doing the
following:
1. Declare the property in the body of the class, not in the primary
constructor.
2. Provide getter and setter methods in the class body.
The full syntax for declaring a property is as follows:
var <property name>:[<property type>][=<initializer>]
  [<getter>]
  [<setter>]

See: CH4-Properties.kt

The field keyword is a special one. It refers to the backing field, which Kotlin
automatically provides when we define a property called name. 
The name member variable isn’t a simple variable; Kotlin makes an automatic backing field
for it, but we don’t have direct access to that variable. We can, however, access it via
the field keyword, like what we did in CH4-Properties.kt. If we try to use the expression
this.name in a get() function to access the member variable name, instead it calls the
default accessor methods that Kotlin provides automatically when you define a property for
the class. So, calling this.name from within an accessor function will result in a tailspin
of recursive calls, and eventually the runtime will throw a StackOverflowError. To prevent
this from happening, you should use the field keyword when referring to the backing field
of a property name from within an accessor function.


Data Classes

See: What exactly are Kotlin Data Classes?

See: CH4-dataclasses.kt

Checking data type and casting in Kotlin with 'is' and 'as'







Chapter 5 - Lambdas and Higher Order Functions


See GitHub








Chapter 6 - Collections and Arrays


See GitHub








Chapter 7 - Generics


See GitHub








Chapter 8 - Android Studio Introduction and Setup


See GitHub








Chapter 9 - Getting started


See Android Studio Project named MyApplication

GitHub






Chapter 10 - Activities and Layouts

Kotlin Basics for Android  and Layouts

Simple Birthday Card app

See Android Studio Project named CH10Hello on GitHub

GitHub






Chapter 11 - Event Handling (TH)


To set up a listener, the View object can set or, more aptly, register a listener object.
Registering a listener means you are telling the Android framework which function to
call when the user interacts with the View object.

See Table 11.1 on p223 and pay particular attention to the fact that
when you set up a listener, there are only 3 parts to the code:
the first if is the View object (e.g. button), the second is the 
setOnClickListener registration function, and the argument to this function
is a View.OnClickListener object with the onClick handler function. 


See p102 (TH) for an explanation of object declarations using the 
object keyword. 
In essence, the object keyword allows us to define 
both a class and its instance all at the same time. 
More specifically, it defines only a single instance of that class, 
which makes this keyword a good way to define singletons in Kotlin.
Object declarations can contain most of the things you can write in class, 
like initializers, properties, functions, and member variables. 
The only thing you cannot write inside an object declaration is a constructor
because as the object is constructed automatically, there is no need for one. 

We substitute the object keyword in place of the class keyword. What this effectively
does is define the class and create a single instance of it. To invoke the functions defined
in this object, we prefix the dot (.) with the name of the object - 
pretty much like how we would call static methods in Java.


See Android Studio Project named: CH11EventAnonymousClass (not yet on GitHub)

GitHub






Android

Android Developer






Android Studio

Install Android Studio

If you are running a 64-bit version of Ubuntu, ***before you install Android Studio***
you need to install some 32-bit libraries with the following command:
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386

[I forgot the step above and had to uninstall then reinstall Android Studio. 
These are the steps I took to uninstall Android Studio, and these steps worked for me.
When reinstalled everything worked fine:
Delete the android-studio folder
Delete the sdk folder if it is in not inside the android-studio directory
Delete ~/.AndroidStudio/, which contains config and system;
Delete ~/.android;
Delete ~/.local/share/applications/jetbrains-studio.desktop, if it exists.
Note: $ ls-al (shows all files including hidden files, 
$ rm -r dirname  This will recursively remove a directory including its contents.]

Meet Android Studio
Before you make a new virtual device, you may need to set the permission on the /dev/kvm directory:
# sudo chmod 777 /dev/kvm

Create an Android Project
How to create and run an Android Project
Set up a device for development
For linux, as per plugdev instructions above, you (as a linux user) need to be in the plugdev group:
$ sudo usermod -aG plugdev $anne
$ id  (see above)

Then for the udev rules (see above), the following is required:

$ sudo -s
# apt-get install android-sdk-platform-tools-common

When you connect your phone to the laptop you're developing on, 
USB debugging must be turned on. Go to: 

Settings -> System -> Advanced -> Developer options -> USB debugging (under "DEBUGGING" - turn on)

Be warned: In Android Studio 4.0.1 (ver June 2020), the source code for Kotlin 
(e.g. MainActivity.kt) is stored in the directory named java: app/src/main/java
Annoying, but legacy. (see also Hagos).

Android App Development using Kotlin
Kotlin Quick Guide for Android Basics in Kotlin






Android UI Layouts

Build a Responsive UI with ConstraintLayout






Android Courses

Android Developer Courses in Kotlin and Java
Android's Kotlin-first approach

Google Codelabs guided tutorials in all things Google, 
e.g. at the time of writing there are 5 courses related to Jetpack Compose 
and one on Jetpack Navigation.

developer.android.com/jetpack/compose/tutorial
From the above, "Note: Jetpack Compose is currently in alpha. 
The API surface is not yet finalized, and changes are planned and expected."

Learn to use Jetpack Compose and Jetpack Room:
Codelabs Android Kotlin Fundamentals Course
Android Room with a View Course






Debugging in Android Studio


Debugging your first Kotlin application
Android Studio Debugger notes by RE (pdf)
Android Studio -> User Guide -> Debug your app
Android Studio Logcat stack trace (Video)
Android Studio Debug Log Messages (Picture)
Android Studio Debugger (Video)






GitHub


GitHub is a website which organises and keeps track of changes 
you make to your project files. It interacts with the Linux command git. 
Both the Linux operating system and the git version control system 
were written by Linus Torvalds.

Git commit basically “records changes to the local repository” 
while git push “updates remote refs along with associated objects”. 
So the first one is used in connection with your local repository, 
while the latter one is used to interact with a remote repository.

GitHub
GitHub User Guide
Jetbrains - Manage projects hosted on GitHub
How to add an Android Studio Project to GitHub (stackoverflow)
How to add an Android Studio Project to GitHub (tutorial)
How to add an Android Studio Project to GitHub and commit new files (video 2 min)
How to get a copy of an Android Studio project from GitHub to your local machine (see first 2 minutes of video)
How to write a good Git Commit Message





Idiomatic Programming

What is idiomatic programming?

From the above:

From the best of my knowledge, it means to write code that is 
well-structured and understandable 
while fully utilizing the language’s ability. 
For example, iterating over a list of variables 
can be done in different ways. 

Taking Python 3 for example:

list = [1,2,3] 
for i in range(0,len(list)): 
    print(list[i]) 



Similarly, another (simpler and idiomatic) way 
to write the same function would be:

list=[1,2,4] 
for element in list: 
    print(element) 


A first step to write idiomatic code 
is to read what guidelines each language has. 
I’d suggest: paulmillr/code-style-guides
Hope it helps!

Ilsa Baqai, Data Engineer (2017-present)
Answered October 16, 2018, 319 views

Kotlin.org Idioms Guide






References

Linux Hint sheet
Textbook 1 pdf: Head First Kotlin by Dawn Griffiths and David Griffiths (pdf) - Password protected
A useful Kotlin reference for non-programmers
Vocabulary for Android Basics in Kotlin
What is an API?
Tutorials on Kotlin and Android
Android Studio Time Savers
AndroidX
Android Jetpack


Further Reading



https://kotlinlang.org/docs/books.html

https://kotlinandroidbook.com/





Valid HTML5!