Posts Tagged - kotlin

Dagger2 (dependency injection)

Dagger2 is a library that allows us to achieve dependency injection. It has three main concepts.

  • @Inject tells dagger which variables to inject.
  • @Module defines how to create the objects that we want to inject.
  • @Component links the two together.

When we make any changes to the data code, we need to rebuild the project and the system will generate for us the classes that we need in order to perform the injections.

Implementation

Go into app.build and add the following

apply plugin: 'kotlin-kapt'

def daggerVersion = '2.13'

dependencies {
	implementation "com.google.dagger:dagger:$daggerVersion"
	implementation "com.google.dagger:dagger-android-support:$daggerVersion
	// kotlin annotation processor
	kapt "com.google.dagger:dagger-compiler:$daggerVersion"
	kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
}

Read More

Android & Kotlin experience cheat sheet

Android

Store secrets

Go to gradle.properties and save it there as key/value pairs. Exclude this file from GIT. This make it harder for others to read your secrets from your repository or using the APK file.

We could use Android’s ProGuard to make this more secure. This doesn’t provide 100% security. The best way is to keep your keys outside the project. Store them in a backend server and retrieve them after authentication. Checkout this article and this one for more information on storing secrets in Android.

MY_KEY = "1029831283712090989087"

Open the app level build.gradle file.

android {
	defaultConfig {
		buildConfigField("String", "API_KEY", MY_KEY)
	}
	
	buildTypes {
		release {
			// this deletes unused classes and files from the APK
			minifyEnabled true
			shrinkResources true
		}
	}
}

Read More

From Java to Kotlin - Exceptions & Collections

Exceptions

In Kotlin there’s no difference between checked and unchecked exceptions. Everything’s unchecked so you don’t need to specify any throws or handle any exceptions.

Try as an expressions

Just like if and when, try introduces an expression.
The returned value is either the last expression in the try block or the last expression in the catch block(s).

val a: Int? = try { parseInt(input) } catch(e: NumberFormatException) { null }

Collections

Kotlin has the same collection interfaces as Java, but it adds two new options.

Queue a collection used to hold multiple elements prior to processing (FIFO with the exception of priority queue)
Deque a collection used to hold multiple elements prior to processing (FIFO or LIFO)

Interfaces Hash table impl. Resizable Array Impl. Tree Impl. Linked List Impl. Hash table + Lined List Impl.
Set HashSet   TreeSet   LinkedHashSet
List   ArrayList   LinkedList  
Queue          
Deque   ArrayDeque      
Map HashMap   TreeMap   LinkedHashMap

Read More

From Java to Kotlin - OOP, Companion Objects & Destructuring in Kotlin

Constructors with default values

The primary constructor is part of the class header. Secondary constructors are declared in the class body.

class User constructor(nickname: String) {
  init {
    // code to execute on Class creation
  }
}

// using default values
class User(val nickname: String, val isSubscribed: Boolean = true)

Secondary Constructors

If a class has a primary constructor, each secondary constructor needs to delegate to the primary constructor

class Person(val name: String) {
  constructor(name: String, parent: Person): this(name) {
    parent.children.add(this)
  }
}

Read More

From Java to Kotlin - Lambdas

A lambda expression is always surrounded by curly braces

// declaration
{ println("I am a function lambda! ") }

// store in a variable
val printer = { println("I am saved!") }

// invoke a stored lambda
run(printer)

// lambdas with parameters
val printMessage = { message: String -> print(message) }

// invoke it
printMessage("hello there!")

Higher Order Functions

A higher order function is a function that either accepts another function as a parameter, returns a function as its return value, or both

Read More

From Java to Kotlin - Standard Library Functions

Kotlin provides a standard library that is meant to augment the java’s standard library.

Apply

It makes code that needs to initialize an instance more readable.

It accepts a lambda that is invoked with the receiver being the instance where apply was called and
returns the original instances.

// without apply
val task = Runnable { print(Running) }
val thread = Thread(task)
thread.setDaemon(true)
thread.start()

// using apply
val task = Runnable { print(Running) }
Thread(task).apply { setDaemon(true) }.start()

Read More

From Java to Kotlin - Functions, Varargs & Default Parameters

Kotlin functions are defined using the fun keyword with optional parameters and a return value (with a exception [Single Expressions]).

fun double(x: Int): Int { }

// calling member functions use the dot notation
Sample().foo()

Single Expressions functions

They mustn’t declare a return type.

fun concat1(a: String, b: String) = a + b

// written in regular style, this would be
fun concat2(a: String, b: String): String {
  return a + b
}

Such functions can use a shortened syntax that omits the braces and uses the = symbol before the expression rather than the return keyword.

Read More

From Java to Kotlin - Control Flow

If as an expression

If branches can be blocks, that when used as an expression, its last value is the returned value of the block.

// java's ternary statement
final String max = a > b ? a : b

// kotlin's if expression
val max = if(a > b) a else b

As an expression, i0f is required to have an else branch.

Read More

From Java to Kotlin - Nullable Types & Null Checks

Nullable

In Kotlin variables cannot be null by default. This prevents many possible exceptions.

// function, with a non-nullable parameter
fun strLen(s: String) = s.length

// function, with a nullable parameter
fun strLen(s: String?) = s.length

Once you have a value of a nullable type, the set of operations you can perform on it are restricted.

  • You can no longer call methods on it.
  • You can’t assign it to a variable of a non-null type.
  • You can’t pass it as a parameter to a function expecting a non-null argument.

To solve this, you need to compare it with null. After this, the compiler remembers that and treats the value as being non-nullable.

Read More

From Java to Kotlin - Operators & Operators Overloading

RangeTo

1..10 enumerates all numbers from 1 to 10
a..b is the same as a.rangeTo(b)

Referential vs Structural Equality

Referential equality. Two separate references point to the exact same instance in memory
=== / !== check if it’s same instance

Structural equality. Two objects are separate instances in memory but have the same value
== / != check if they have the same values

Read More

From Java to Kotlin - Data Types, String Templates & Casting

Number Types

The built-in number types are as follows

Type Bytes
Long 64 bytes
Double 64 bytes
Int 32 bytes
Float 32 bytes
Short 16 bytes
Byte 8 bytes

The conversion methods are toByte() toShort() toInt() toLong() toFloat() toDouble() toChar()

// how to convert between types
fun main(args: Array<String>) {
    val minutesInYear: Double = (60*24*365).toDouble()

    val input = Scanner(System.`in`)
    print("Input the number of minutes: ")
    val min = input.nextDouble().toInt()

    val years = (min / minutesInYear.toLong())
    val days = (min / 60.0 / 24.0).toInt() % 365

    println("$min mins is approx $years years and $days days")
}

Read More

From Java to Kotlin - Kotlin vs Java & Tools

Java features that Kotlin lacks

  • Checked exceptions
  • Primitive types that aren’t classes
  • Static members
  • Non-private fields
  • Wildcard types

Functional Programming in Kotlin

What is Functional Programming

Creating software by writing functions, avoiding shared state, using immutable data and causing no side-effects.

It’s declarative rather than imperative. Application state flows through pure functions.

Declarative program logic is expressed without explicitly describing the flow control.
Functional Programming uses lots of generics and reusable code (lambdas).

Read More

From Java to Android with Kotlin

(Disclaimer: This are my personal notes from following Kotlin and Android courses in Udemy. This is a watered-down version from those courses. Check and buy the original courses if you want to find the full resources I used with more detail)

Android

This are my notes on the progress of things I had to learn to go from Java Developer to develop my first Android App with Android in Kotlin.

1. ViewBinding
2. DataBinding
3. MVVM Architecture
4. Live Data
5. ViewModel, LiveData, DataBinding
(wip: I still have to order and clean this series of posts from here on)
6. Recycler View
7. Navigation Architecture Component
8. Android Notifications
9. Coroutines
10. WorkManager
11. Android Testing

Extras:
12. Dagger2 Framework (dependency injection)
13. Hilt Framework (Dagger2 wrapper)
14. Room Framework (SQLite)
15. Android SQLite experience sheet
16. Android Development experience

Kotlin

This series of posts explain the main differences in language structures and usage between Kotlin and Java languages. I don’t explain the full Kotlin language, but the novelties that Kotlin implements that may be of interest to a Java developer.

1. From Java to Kotlin - Data Types & Casting
2. From Java to Kotlin - Operators & Operators Overloading
3. From Java to Kotlin - Nullable Types & Null Checks
4. From Java to Kotlin - Control Flow
5. From Java to Kotlin - Functions, Varargs & Default Parameters
6. From Java to Kotlin - Standard Library Functions
7. From Java to Kotlin - Lambdas
8. From Java to Kotlin - OOP, Companion Objects & Destructuring in Kotlin
9. From Java to Kotlin - Exceptions & Collections

Extras:
10. Kotlin cheat sheet with code examples

Read More

Spring CORS

CORS (Cross-Origin Resource Sharing)

It’s a mechanism to let a web application running at one domain, protocol or port have permission to access resources from a server at a different one.

This is needed if you have, for example, a Frontend running on port :3000 (React) consuming a Backend API running on port :34831 (custom port for Spring). Unless CORS are set, FE will not be able to access BE resources.

In Spring

It’s possible to enable them for a single RestResource or globally for the whole application.

(This example has been done in Kotlin)

By RestResource

@RestController
@RequestMapping("courses")
@CrossOrigin("http://localhost:3000")
class CourseRestResource {
  // dependencies and methods
}

Read More