In our previous blog, we introduced Koin and set up a simple "Hello Koin" example to demonstrate dependency injection. Now, let’s take it a step further and explore how to integrate Koin with Jetpack Compose. This guide will help you leverage Koin to manage dependencies seamlessly in a modern Compose-based Android application.
Jetpack Compose is Android’s modern UI toolkit, and Koin’s Kotlin-first approach makes it an ideal match. Together, they provide:
Simplified dependency management: Koin handles dependencies, freeing you from manual instantiation.
Cleaner code: Compose’s declarative UI and Koin’s DSL complement each other for concise, readable code.
Scalability: Easy to manage dependencies across a growing application.
Add the following dependencies to your build.gradle
file:
implementation "io.insert-koin:koin-android:3.x.x"
implementation "io.insert-koin:koin-androidx-compose:3.x.x"
Replace 3.x.x
with the latest version of Koin.
Let’s create a module for our Compose-based app. Assume we have a GreetingService
to provide messages:
class GreetingService {
fun getGreeting() = "Hello from Koin!"
}
val appModule = module {
single { GreetingService() }
}
Initialize Koin in your Application
class:
import android.app.Application
import org.koin.core.context.startKoin
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
modules(appModule)
}
}
}
Declare the Application
class in your AndroidManifest.xml
file:
<application
android:name=".MyApplication"
...>
</application>
Koin provides seamless integration with Compose using the koinComponent()
and get()
functions.
Here’s an example:
import androidx.compose.runtime.Composable
import androidx.compose.material3.Text
import org.koin.androidx.compose.koinInject
@Composable
fun GreetingScreen() {
val greetingService: GreetingService = koinInject()
Text(text = greetingService.getGreeting())
}
In this example:
koinInject()
retrieves the GreetingService
instance from Koin.
The GreetingService
is then used to display a greeting message.
In your MainActivity
, set the Compose content:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.MaterialTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
GreetingScreen()
}
}
}
}
When you run the app, the GreetingScreen
will display the text: Hello from Koin!
.
Koin offers additional features for Compose integration, such as:
Koin’s viewModel()
delegate simplifies ViewModel injection in Compose. Here’s an example:
import androidx.lifecycle.ViewModel
class GreetingViewModel(private val greetingService: GreetingService) : ViewModel() {
fun getGreetingMessage() = greetingService.getGreeting()
}
val viewModelModule = module {
viewModel { GreetingViewModel(get()) }
}
import androidx.compose.runtime.Composable
import org.koin.androidx.compose.koinViewModel
@Composable
fun GreetingScreen(viewModel: GreetingViewModel = koinViewModel()) {
Text(text = viewModel.getGreetingMessage())
}
Koin supports parameter injection for more dynamic behavior. For instance:
val appModule = module {
factory { (name: String) -> GreetingService(name) }
}
@Composable
fun GreetingScreen() {
val greetingService: GreetingService = get { parametersOf("Compose") }
Text(text = greetingService.getGreeting())
}
Akshay Nandwana
Founder AndroidEngineers
You can connect with me on:
Join our upcoming classes
https://www.androidengineers.in/courses