Blog Infos
Author
Published
Topics
Published
Topics

Koined from original banner — https://github.com/android/nowinandroid

 

This year I was speaking at several Android conferences, about Android architecture design with Koin (Silicon Brighton) and about the new Kotlin developer experience since Koin 3.2 (Droicon Berlin and Kotlin Dev Day Amsterdam).

At the same time, the Google Android team was heavily working on gathering best practices for the community, related to the latest development technologies such as Jetpack Compose, Material Design Kotlin Coroutines, and other technologies standards to build Android applications in 2022.

Now In Android is an open-source Android application that covers those best practices and keeps them up to date. The app is maintained by the Android team. A great thanks to them for such resources!

I propose today to take a special tour of Now In Android: a version built with the Koin dependency injection framework. This is a good time to refresh practices with Koin and Modern Android Development, from standard components structure to more advanced cases.

You can find all the related sources at this location: https://github.com/InsertKoinIO/nowinandroid

This article is split into several parts:

Part 1 — Koin setup, application verification, and a first module tour

Part 2 — Common Modules components (database, network, domain …) and feature modules

Part 3 — Setup and code with Koin annotations

… perhaps more 🙂

Injecting with Koin

Koin is a very popular Kotlin dependency injection framework (https://insert-koin.io/), well-known for its ease of use and its capacity to bring elegant and powerful features thanks to the Kotlin language.

In Android, Koin comes magically ready to use out of the box thanks to the Kotlin extensions mechanism. This means that you can easily use Koin functions directly from any Android part.

The Now In Android (aka Niaapplication is a vast example to play with. Great content, but where to start? 🤔

Features picture from https://github.com/android/nowinandroid

Architecture & Modules Map

The project proposes an overview of the existing modules. You may take a look at the modularization document. Here is a quick preview of the organization of the current modules:

Module organization — https://github.com/android/nowinandroid

We can explore the project on the following parts:

  • App Module — the main module and application entry point
  • Common modules — gathering all common components (database, repository, network, domain …)
  • Feature modules — implementing each part/screen of the app
  • Sync module — dedicated to data resyncing
Gradle Setup & Build logic for Koin

First, let’s setup everything. We use the following Koin dependencies in the project:

  • koin-android — Android features (common android parts)
  • koin-androidx-compose — features related to Jetpack Compose (feature module)
  • koin-androidx-workmanager — WorkManager features (common data sync module)
  • koin-core — pure Kotlin components (for Kotlin only common module)
  • koin-test — verification and testing parts

For this articles series, we will use the latest Koin 3.3 versions. Check the setup page for more details: https://insert-koin.io/docs/setup/koin

The Gradle configuration has been updated to be able to use Koin package directly with the version catalog already established. Check the libs.versions.toml file about Koin artifacts.

The AndroidFeatureConventionPlugin file is also updated to bring koin-androidx-compose for each feature module.

Starting Koin

Let’s open the NiaApplication class, the application entry point, to see the onCreate method written to start Koin with startKoinfunction:

Starting Koin

Job Offers

Job Offers


    Android Software Engineer (f/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

    Android Test Automation Engineer

    Komoot
    Remote
    • Full Time
    apply now

    Senior Android Software Engineer (f/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

OUR VIDEO RECOMMENDATION

,

Diving into Koin 3.2 & Koin Annotations 1.0

​​Koin is the Kotlin dependency injection framework well known for its ease of use and efficiency. It has been greatly appreciated by the Android community since 2017. In 2022, a new major version of the…
Watch Video

Diving into Koin 3.2 & Koin Annotations 1.0

ARNAUD GIULIANI
Koin Project Lead

Diving into Koin 3.2 & Koin Annotations 1.0

ARNAUD GIULIANI
Koin Project Lead

Diving into Koin 3.2 & Koin Annotations 1.0

ARNAUD GIULIANI
Koin Project Lead

Jobs

We use several options:

  • androidLogger — enable Koin logging on an Android
  • androidContext— reference the Android Application context
  • workManagerFactory— start WorkManager components declared in Koin

We use the modules() function to load Koin modules. Here we will load the niaAppModule.

The call toSync.initialize() will init the WorkManager to resync data. We will look at these details later.

note: androidLogger is logging in INFO level by default. You can choose the DEBUG level to have more complete information if you need to investigate around Koin.

The Nia Application Module

The first thing we need is one main module that will include all other sub-modules. The NiaAppModule.kt file declares the main Koin module as follow:

The main Koin module

The includes function uses a list of modules to load with the current module. This also helps Koin flatten all your module graphs and optimizes your application startup.

Below we declare MainActivityViewModel as a ViewModel in Koin, with the viewModelOf() function. This function targets directly a class constructor to build.

viewModelOf(::MainActivityViewModel)

This is why we have the use of :: characters, to identify the constructor of the MainActivityViewModel class.

We recommend using includes() function to ensure gathering all app modules into the main one. More than helping organize modules and sub-modules, the includes function will let you verify globally your Koin configuration. Let’s check below.

Verifying the Koin Configuration — verify() your module

One new important feature of Koin introduced recently with Koin 3.3, is the capacity to verify a Koin configuration in a few milliseconds with just a JUnit test. The koin-test Gradle package is required to have access to such testing features.

How does it work? Use the verify() extension function on a Koin Module. That’s it! Under the hood, This will verify all constructor classes and crosscheck with the Koin configuration to know if there is a component declared for this dependency. In case of failure, the function will throw a MissingKoinDefinitionException.

Let’s see the NiaAppModuleCheck.kt file:

verify() on the main Koin module

Launch the JUnit test and you’re done! ✅

As you may see, we use the extraTypesparameter to list types used in the Koin configuration but not declared directly. This is the case for SavedStateHandle and WorkerParameters types, that are used as injected parameters. The Context is declared by androidContext() function at start.

The verify() API is ultra-light to run and doesn’t require any kind of mock/stubb to run on your configuration.

First module & injection from an Activity

Let’s continue our exploration of the project, still in the app module. There is a small module that let you build JankStats instances for an Activity: the JanksStatsModule .

Below is the original dagger version:

JankStatsModule in Dagger version

The idea is to create a JankStats object to let you enable/disable performance tracking in an Activity:

Lazy Dagger Property for JankStats

Using lazyStats

In the Koin version, we would write this part with a simple definition. Let’s open the JankStatsKoinModule file:

JankStats Koin module

Here we have a factory definition, that is building the JankStats object instance from an incoming Activity.

How do we pass an Activity to a definition? We use injected parameters to declare that we will use an Activity as a parameter:

factory { (activity: Activity) -> JankStats.createAndTrack(activity.window, createOnFrameListener()) }

We use a function (lambda block behind factory keyword), to write a Kotlin function that will build our component.

From our MainActivity, we simply need to declare JankStats with a call to injectfunction as follow:

val lazyStats: JankStats by inject { parametersOf(this) }

The parametersOf expression passes arguments to your Koin definition.

 

Lazy inject in Activity with Koin & injected parameters

 

The lazyStats property is a real Kotlin lazy type and can be used directly used:

 

 

Well … That’s it for this first part. Hope you enjoyed it. See you in the next part about common components and features.

Follow Koin and Kotzilla latest news on http://blog.kotzilla.io/

This article was originally published on proandroiddev.com on December 15, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
This is the second article in an article series that will discuss the dependency…
READ MORE
blog
I develop a small multi-platform(android, desktop) project for finding cars at an auction using…
READ MORE
blog
Now In Android is an open-source Android application that covers Modern Android Development best…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu