Skip to content

Instantly share code, notes, and snippets.

@h4k1m0u
Last active April 22, 2025 20:18
Show Gist options
  • Save h4k1m0u/747a60c86f4664fe4520590badae4f03 to your computer and use it in GitHub Desktop.
Save h4k1m0u/747a60c86f4664fe4520590badae4f03 to your computer and use it in GitHub Desktop.
Notes about coding Android apps with Kotlin using Android Studio

Kotlin

  • Statically typed language.
  • Outputs bytecode that runs on the JVM (like Java).

Build Automation tools for JVM projects

All of them are similar to CMake but for Java/Kotlin:

  • Gradle: Build system for Android used for compilation, packaging (APK), and for dependency management. Preferred for Kotlin projects.

  • Maven: Used mainly in Java projects.

  • Ant: One of the oldest java build tools.

Android KTX

Kotlin extensions for Android development.

Android Jetpack

Suite of libraries to simplify Android app development.

Thirdparty libraries

  • OkHttp: Http client library.

  • Retrofit: higher-level Http client library built on top of OkHttp. Practical for communicating with a webservice.

  • Gson: Used to convert Java objects to Json and vice versa (i.e. serialization and deserialization).

  • Ktor: Kotlin framework for building Http clients (like OkHttp) and http servers (like express.js).

  • Spring Boot: Java web framework built on top of Spring (similar to Django).

Jetpack Compose

Toolkit for building Android UI in Kotlin (replacement for XML UI) that has the following concepts and elements:

  • @Composable: tells the compiler that this function is used by Jetpack Compose to generate UI.
  • Functions with the @Composable annotion can be called from setContent() or any other composable function.
  • androidx namespace comprises the Android Jetpack libraries (e.g. Compose).

Composable functions

  • Composable functions should be side-effect free as recomposition is unpredictable (e.g. could be skipped).

  • Example of a side-effect: updating global variable.

  • Expensive operations should go in a background coroutine, and its result passed to the composable function.

Elements

  • Scaffold: Structure that holds together different UI parts (topbar, drawer menu, bottom bar, floating action button...), in order to have a coherent look and feel.
  • Layouts:
    • Column: places items vertically.
    • Row: places items horizontally.
    • Box: places items on top of one another.
  • Modifier: customizes and configures UI elements.
  • Surface: provides a surface with a background and an elevation.

State

  • Composition: Initial rendering of UI by executing composable functions.
  • Recomposition: Re-running composables to update UI when state changes.
  • State and MutableState make state observable by Compose (i.e. Compose tracks each composable that reads state properties, and triggers a recomposition when state's value changes).
  • remember() stores the value across recomposition (i.e. refresh), so it's not reset on the next partial rendering.
  • rememberSaveable() is like remember() but also makes the state survive configuration changes (e.g. screen rotations).
  • var count by remember { mutableStateOf(0) }: delegates calls to get() and set() methods of count to getValue() and setValue() methods resp. of the mutable returned by remember().

Design patterns

Unidirectional data flow

  • Design pattern that decouples the UI (i.e. composables) from parts that store/change the state.
  • ViewModel (called a state holder) manages the UI state & handles events.
  • Events flow up (Composable -> ViewModel), and state observed by composable flows down (ViewModel -> Composable).

MVVM

  • Model: Data layer (Room entity, Repository).
  • View: UI (Composable, Activity).
  • ViewModel: Link between the Model and the View.

Communication

  • ViewModel -> Model: requests data.
  • Model -> ViewModel: returns data.
  • View -> ViewModel: observes state & update automatically when it changes.
  • View -> ViewModel: UI events trigger ViewModel function calls.

Data layer

  • Repository: handles data retrival from different data sources (local database, remove API...).

ViewModel

  • On each configuration change (e.g. screen rotation, changing to dark theme), activity is destroyed & re-created.
  • Solution: Use Android's ViewModel to save state, as it outlives the life cycle of its activity.

Flows

Flow

  • Stream of values computed async.
  • Flows are cold, i.e. they don't run till flow is collected.
  • Collecting the flow performed without blocking (in a suspending manner, inside runBlocking()).

SharedFlow

  • Hot flow, i.e. emits values regardless of whether there are collectors or not.
  • Broadcasts emitted values to multiple collectors.
  • Useful for broadcasting events in an app to subscribers.

StateFlow

  • Holds a single updatable value (latest value of the state).
  • Emits updates to its collectors when value changes.
  • Hot flow, i.e. exists even with no collectors.
  • Mainly used in ViewModel to store and expose UI state to UI components.
  • Modern replacement of LiveData in JetPack Compose and coroutines.

LiveData

  • Android-specific unlike StateFlow.
  • Its observers receive updates only if Activity is an active state (started or resumed).
  • Follows the Observer pattern (i.e. notifies observer objects when underlying data changes).

LaunchedEffect

  • Used to call suspend functions (i.e. coroutines) inside a composable.

  • Runs a coroutine when its key parameter changes.

  • Old coroutine call is cancelled before each re-launch.

  • Coroutine also relaunched once composable (one calling the coroutine) has left composition or is removed from UI.

  • Common uses: Animations, one-time UI events (e.g. Show a snackbar).

How to build & run

# -include-runtime to work with lists for instance
$ kotlinc -verbose -include-runtime -d hello.jar *.kt
$ java -jar hello.jar

Visibility modifiers

  • Class members (methods and properties) are public by default.
  • Use private to make them visible inside the class only.

Reactive programming

Programming paradigm concerned with async data streams and the automatic propagation of change (e.g. Flow in Kotlin).

Coroutines

  • Wikipedia definition: Functions that pause and resume execution without blocking.
  • In Kotlin: runs concurrently with the rest of the code (similar to a thread, but more lightweight).

Suspend functions

  • A function that can be paused and resumed, and that runs inside a coroutine.
  • It can be called within a coroutine scope or from another suspend function.

launch()

  • Run a coroutine concurrently (without blocking the current thread).
  • Runs in a coroutine scope. I.e. inside runBlocking() block for non-Android apps, or in ViewModelScope or lifecycleScope (for Activity) in Android apps.

Object declaration

  • Used to define a class & create an instance of it (i.e. singleton) in a single step.
  • Cannot have a constructor (primary or secondary).

Data class

Used to implement a POJO (Plain old Java object) but with auto-generated methods (e.g. to print object in readable format, to compare instances...).

Data object

  • Similaly to data classes, has a few auto-generated methods (toString(), equals()).
  • But has a single instance at runtime.

Sealed classes

  • Has a fixed number of subclasses known at compile time.
  • Subclasses must be declared in the same package as the sealed class.
  • Used to hold state (e.g. UI state).
  • In contrast with enum, each state (i.e. subclass) can hold non-const data.
  • data class commonly used for states holding data, and data object (i.e. singleton) for those that don't.
  • They support polymorphism, just like interfaces and abstract classes.

Lazy

  • The value of an instance of type Lazy is calculated on the first access.
  • Subsequent calls only return remembered results.
  • e.g. The value returned by ComponentActivity.viewModels().

Introspection

  • MyClass::class: gives a reference to the Kotlin class MyClass.

Receiver object

  • Receiver object passed to a function call becomes the implicit this, so that its member methods can be accessed inside this same function.

  • An instance of the receiver is provided implicitely inside the function.

  • e.g. Canvas' onDraw lambda parameter.

Room

  • Database: main access point to database. Lists entities and DAO methods below.
  • Entity: Reprensent tables in the database (each instance is a row in the table).
  • Data Access Object (DAO): Methods to used to CRUD in the database
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment