Android Kaki

Build beautiful, usable products using required Components for Android.

Now in Android with Koin — half 4 | by Arnaud Giuliani | April 2023

Coined from the unique banner –

Now in Android is an open supply Android utility that features trendy Android Improvement finest practices. The challenge is maintained by the Google Android crew.

I counsel persevering with our tour with model constructed with Koin . dependency injection framework. It is a good time to refresh strategies, from normal part constructions to extra superior instances.

For this text, Now I counsel utilizing Koin Annotations as a substitute of Koin DSL to configure all of the parts of the applying. That is attention-grabbing to see how a lot it may possibly enhance the writing expertise.

Put together yourselves, we have now lots to see collectively 👍

⚠️ The model used under has not been made public. @KoinWorker coming quickly in subsequent launch

Beforehand partially 3, we noticed learn how to arrange and use Koin annotations with the Koin dependency injection framework. It is very easy as a result of the Koin annotation processor can detect a number of situations and create your dependency injection configuration actually quick. Now it is time to dive into extra parts of the NowInAndroid challenge.

You should have references for all content material to browse the code. Additionally, all the things is out there on-line on the Github repo:

Following the article half 2, we’ll now go to study the widespread core parts that can be utilized by the next options. However this time, the configuration can be achieved with annotations.

As a reminder, the Nia app is developed utilizing Jetpack Compose and makes use of repository parts & use instances:

  • Warehouse to entry knowledge (community, database, and many others.)
  • Usecase handles enterprise logic

The module is gathering all of the widespread parts which might beDataKoinModule.kt module:

@Module(contains = [DaosKoinModule::class, DataStoreKoinModule::class, NetworkKoinModule::class, DispatchersKoinModule::class, DataUtilModule::class])
class DataKoinModule

This module is doing a number of issues:

  • scan all repository lessons outlined in @ComponentScan
  • embody modules which might be declaring subclass parts

Every repository class is just tagged with @Single Annotate like this:

class OfflineFirstAuthorsRepository(
personal val authorDao: AuthorDao,
personal val community: NiaNetworkDataSource,

You could find all of the repository lessons in supply code package deal.

For the database storage class, we have to declare our Room database occasion through a operate utilizing the Room API generator as follows:

class DatabaseKoinModule {

enjoyable database(context: Context) =
Room.databaseBuilder(context,, "nia-database")

The context the parameter right here is the Android Context model from Koin.

Within the second module we are able to reuse NiaDatabase instance under in DAO:

@Module(contains = [DatabaseKoinModule::class])
class DaosKoinModule {

enjoyable authorDao(niaDatabase: NiaDatabase) = niaDatabase.authorDao()

enjoyable topicDao(niaDatabase: NiaDatabase) = niaDatabase.topicDao()

enjoyable newsResourcesDao(niaDatabase: NiaDatabase) = niaDatabase.newsResourceDao()

That is it! Our database layer is able to be included.

This class defines Knowledge Sources that are parts that summary away calls to totally different knowledge sources. For instance, distant net service, native knowledge storage, and many others. Due to this fact, the consumer interface would not must know the place the information is coming from. It simply calls the interface outlined right here.

We’re defining some sort of usages with NiaNetworkDatasource:

interface NiaNetworkDataSource {
droop enjoyable getTopics(ids: Record<String>? = null): Record<NetworkTopic>

droop enjoyable getAuthors(ids: Record<String>? = null): Record<NetworkAuthor>

droop enjoyable getNewsResources(ids: Record<String>? = null): Record<NetworkNewsResource>

droop enjoyable getTopicChangeList(after: Int? = null): Record<NetworkChangeList>

droop enjoyable getAuthorChangeList(after: Int? = null): Record<NetworkChangeList>

droop enjoyable getNewsResourceChangeList(after: Int? = null): Record<NetworkChangeList>

First, we have to declare a default Coroutine dispatcher instantly in a module:

class DispatchersKoinModule{

enjoyable dispatcher() = Dispatchers.IO

IN a take a look at setting, you solely must redefine one CoroutineDispatcher kind to specify your wanted one. Simply add a brand new definition and it’ll overwrite the prevailing one.

The community module declaring NiaNetworkDatasourceand arranged into 2 flavors:

  • demo — with native knowledge
  • prod — for on-line knowledge

The NetworkKoinModule together with the right implementation of the style:

@Module(contains = [FlavoredNetworkKoinModule::class])
class NetworkKoinModule {

enjoyable json() = Json { ignoreUnknownKeys = true }

Demo taste within the Community module

The demo taste makes use of the Knowledge Warehouse API and the Protobuff API is used to retailer knowledge regionally for rendering as an offline most well-liked structure.

@Module(contains = [DispatchersKoinModule::class])
class FlavoredNetworkKoinModule{

enjoyable assetManager(context: Context) = FakeAssetManager(context.belongings::open)

Right here is the demo datasource implementation declared as a singleton:

class FakeNiaNetworkDataSource(
personal val ioDispatcher: CoroutineDispatcher,
personal val networkJson: Json,
personal val belongings: FakeAssetManager = JvmUnitTestFakeAssetManager,
) : NiaNetworkDataSource

The web model is said with the next module:

@Module(contains = [DispatchersKoinModule::class])
class FlavoredNetworkKoinModule

This module will scan Retrofit implementations:

class RetrofitNiaNetwork(
networkJson: Json
) : NiaNetworkDataSource

A last part is in regards to the persistent knowledge storage API, which is used to declare native knowledge storage. Test Knowledge Warehouse Persistence Module that’s to declare the required parts for NiaPreferencesDatasource.

Earlier than working our options, we have now some use case parts utilizing DataKoinModule. These use case parts are reusable enterprise logic parts. They’re outlined from DomainKoinModule:

@Module(contains = [DataKoinModule::class])
class DomainKoinModule

You might notice that we don’t specify which packages to scan. Which means the module will scan within the present package deal and subpackages for annotated parts:

Every usecase aspect is said with @Manufacturing facility notice. This tells Koin to create a brand new occasion every time we’d like it.

@Manufacturing facility
class GetFollowableTopicsStreamUseCase(
personal val topicsRepository: TopicsRepository,
personal val userDataRepository: UserDataRepository

Why not a single instance? As a result of these usecase parts can be used with a ViewModel, which follows the Android lifecycle. Making them a unit, we run the danger of getting references to a ViewModel canceled by the applying.

Lastly, we’re prepared to make use of all of those in our Options module. Each will then embody DomainKoinModule or DataKoinModule To learn from the favored components:

@Module(contains = [DomainKoinModule::class,StringDecoderKoinModule::class])
class AuthorKoinModule

By correctly scanning the package deal in our module, we will declare our ViewModel situations as follows:

class AuthorViewModel(
savedStateHandle: SavedStateHandle,
stringDecoder: StringDecoder,
personal val userDataRepository: UserDataRepository,
authorsRepository: AuthorsRepository,
getSaveableNewsResourcesStream: GetSaveableNewsResourcesStreamUseCase
) : ViewModel()

Lastly, we have to declare SyncWorker parts to organize offline content material asynchronously. This features a module:

class SyncWorkerKoinModule

The next definitions can be scanned by the module.

class WorkManagerSyncStatusMonitor(
context: Context
) : SyncStatusMonitor

And SyncWorker declared aspect with @KoinWorker notice. This can produce the equal of employee { } DSL:

class SyncWorker (
personal val appContext: Context,
workerParams: WorkerParameters,
personal val niaPreferences: NiaPreferencesDataSource,
personal val topicRepository: TopicsRepository,
personal val newsRepository: NewsRepository,
personal val authorsRepository: AuthorsRepository,
personal val ioDispatcher: CoroutineDispatcher,
) : CoroutineWorker(appContext, workerParams), Synchronizer

SyncWorker can be declared with the Workmanager Koin manufacturing unit. This needs to be enabled from the beginning like this:

Koin begins in NiaApplication class

John Wick: Chapter 4 (FREE) FULLMOVIE The Super Mario Bros Movie avatar 2 Where To Watch Creed 3 Free At Home Knock at the Cabin (2023) FullMovie Where To Watch Ant-Man 3 and the Wasp: Quantumania Cocaine Bear 2023 (FullMovie) Scream 6 Full Movie

Supply hyperlink

Updated: April 4, 2023 — 8:53 pm

Leave a Reply

Your email address will not be published. Required fields are marked * © 2023 Android kaki