0

I am using Hilt as DI in my Android Studio project.

ServiceTranslate is a Service class that has a longer lifecycle than the app itself. The ServiceTranslate will invoke the TranslateIncompleted class to perform tasks in the background.

1: Currently, I am using @ApplicationContext private val appContext: Context in the TranslateIncompleted class. I believe appContext is an instance of the UIApp class, is that correct?

2: Will the app crash when the app is destroyed but ServiceTranslate continues to run in the background?

class TranslateIncompleted @Inject constructor(
   @ApplicationContext private val appContext: Context       //I'm afriad  that it maybe cause trouble.
): ITranslateIncompleted {

    override suspend fun translateIncompletedAndUpdate() {
        val myString = appContext.getString(R.string.translate_incompleted)        
    }
}


@AndroidEntryPoint
class ServiceTranslate: Service() {

    @Inject lateinit var translateIncompleted: ITranslateIncompleted
 
    inner class MyBinder : Binder() {
        val serviceTranslate: ServiceTranslate
            get() = this@ServiceTranslate
    }

    override fun onBind(intent: Intent): IBinder {
        return MyBinder()
    } 
}


@HiltAndroidApp
class UIApp : Application() {

}
HelloCW
  • 843
  • 22
  • 125
  • 310

2 Answers2

3

ServiceTranslate is a Service class that has a longer lifecycle than the app itself

I don't think this statement is correct. An instance of Application should always exist if the process is running, which would be the case if the Service is active. Unless you are running your Service in it's own process, using AppContext should be entirely safe, as Service will always have an associated Application. You can validate this by putting a log statement in onDestroy of Application, and confirm that it's not called when the app get's backgrounded in the UI while the Service is still active. Related thread

Alternately, you could sidestep this concern entirely by exposing Service.getResources() on the Service's DI graph. That way, you wouldn't need to depend on the Application Context.

Johno
  • 31
  • 1
  • Application context is directly available from Service itself. So there is no issue. Application class will live more than Service. – Sangeet Suresh Jun 05 '23 at 14:59
1
  1. Yes, when using @ApplicationContext with Hilt, you're indeed getting an instance of your application class, UIApp in your case.

  2. The Application context in Android is a singleton and lives for the entire lifecycle of the application. In your case, you are injecting the Application context, and as this lives as long as your entire application, it will not cause a crash even if the Service is running and the app's activity is destroyed. Your ServiceTranslate can continue to run and have valid access to the appContext.

Nazanin Nasab
  • 595
  • 8
  • 18
  • Thanks! Is there some official document to proof it? – HelloCW Jun 08 '23 at 00:09
  • `@ApplicationContext` providing the application instance is indicated in the Hilt documentation. It specifies that `@ApplicationContext` injects the `Context` of the Application subclass: https://dagger.dev/hilt/entry-points.html – Nazanin Nasab Jun 08 '23 at 06:58
  • The lifetime of the Application context is mentioned in the Android documentation on the Application class. It's stated there that the `Application class`, or your application context, "is instantiated before any other class when the process for your application/package is created.": https://developer.android.com/reference/android/app/Application – Nazanin Nasab Jun 08 '23 at 07:02
  • Additionally, the documentation for `Services` explains that a Service can run in the background even when the user is not interacting with the application, which means it is not tied to the Activity lifecycle: https://developer.android.com/guide/components/services hope these help @HelloCW – Nazanin Nasab Jun 08 '23 at 07:09
  • @HelloCW could you be confusing the Application class (`UIApp` in your example) with an Activity? All Android Apps start at Application and from there _everything else_ exists, so your service will not exist without an Application class instantiated in memory, but can exist without an active Activity (through a service for example). – Martin Marconcini Jun 19 '23 at 14:52