0

I was starting the foreground service by manually binding and then using its method.

However, I recently came across Koin and found https://insert-koin.io/docs/reference/koin-compose/compose

@Composable
fun App(myService: MyService = koinInject()) {
}

Now, This gave me the idea that Koin would do the binding for me, and I'll be able to use the method of the Service directly without binding and unbinding of service using ServiceConnection

But, I get,

java.lang.NullPointerException: class name is null

On startForeground call inside service.

and,

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

On, any super member call.

Now, either I'm not properly setting up Koin, or Koin doesn't support Service (even if I manually bind it, but use the service instance from Koin it still crashes with the same issue).

I'd like experts' opinions here, cuz the docs mention MyService, but not being able to use SuperClass 'Service' member seems like that was a poor choice for a class name.

Cyber Avater
  • 1,494
  • 2
  • 9
  • 25
  • Koin won't handle the Android Service lifecycle or starting a foreground service for you. You'll still need to handle those aspects yourself. – Polarcode Jul 27 '23 at 06:58
  • @Polarcode I've tested just now and edited the op, please check ` (even if I manually bind it, but use the service instance from Koin it still crashes with the same issue)` – Cyber Avater Jul 27 '23 at 07:00
  • The example of `MyService` in koin docs is not an android service, its a service that holds business logic. You can bind your android service in just a traditional way. – Asad Mahmood Jul 27 '23 at 07:16
  • @AsadMahmood Are you sure? (I had the same feeling actually) However, if you're sure then you can post it as an answer. And in the meantime, I'll try to raise an issue in their GitHub to update the docs and see what they have to say. – Cyber Avater Jul 27 '23 at 07:21
  • @CyberAvater yup 100 % sure! And you don't need to raise an issue as `service`, `usecases` are interchangeable names for domain layer class that holds business logic in clean architecture – Asad Mahmood Jul 27 '23 at 07:26

2 Answers2

1

The example of MyService in koin docs is not an android service, its a service that holds business logic. service, usecases are interchangeable names for domain layer class that holds business logic in clean architecture. You can bind your android service in just a traditional way.

Asad Mahmood
  • 532
  • 1
  • 5
  • 15
0

Koin won't handle the Android Service lifecycle or starting a foreground service for you. You'll still need to handle those aspects yourself.

Example of how you can use Koin for dependency injection with your foreground service:

Setup the koin module

val myModule = module {
    single { MyService() } // Replace MyService() with your actual implementation of the service
}

Initialize Koin in your Application class

class MyApplication : Application() {
override fun onCreate() {
    super.onCreate()
    startKoin {
        androidContext(this@MyApplication)
        modules(myModule) // Define your Koin modules here
    }
}

}

Your Gradle

implementation "org.koin:koin-core:$koin_version"
implementation "org.koin:koin-androidx-scope:$koin_version"
implementation "org.koin:koin-androidx-viewmodel:$koin_version"
implementation "org.koin:koin-androidx-compose:$koin_version" // If you're using Koin with Compose

In your Composable function, you can inject the service using koin.get() and use it directly

@Composable
fun App() {
    val myService: MyService = koin.get() // Inject the service

    // Use myService methods here
}

Remember that Koin doesn't handle the lifecycle of Android components like Activities or Services. You need to start and stop your service explicitly, either manually or through other components (e.g., Activities, BroadcastReceivers).

Polarcode
  • 309
  • 6
  • To `Initialize Koin in your Application class` step I've done exactly the same. now in your next step, you're injecting MyService in MyForegroundService, private val myService: MyService by inject() but in my case, MyService is the Foreground service! And I tried injecting it directly into a composable @Composable fun App(myService: MyService = koinInject()) { } – Cyber Avater Jul 27 '23 at 07:12
  • @CyberAvater see my updated answer if it works. – Polarcode Jul 27 '23 at 07:15
  • Make sure you run your application with the custom class, in my case above I used `MyApplication`. – Polarcode Jul 27 '23 at 07:18
  • Make sure `MyService` is initialized properly. If it requires any context or dependencies during initialization, make sure they are provided in the Koin module. – Polarcode Jul 27 '23 at 07:19