Can I use “@ApplicationContext private val appContext: Context” as DI for a class that will be invoked by a Service() in Android Studio?

huangapple go评论66阅读模式
英文:

Can I use “@ApplicationContext private val appContext: Context” as DI for a class that will be invoked by a Service() in Android Studio?

问题

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: 目前,我在 TranslateIncompleted 类中使用 @ApplicationContext private val appContext: Context。我认为 appContextUIApp 类的一个实例,这正确吗?

2: 当应用程序被销毁但 ServiceTranslate 仍在后台运行时,应用程序会崩溃吗?

class TranslateIncompleted @Inject constructor(
   @ApplicationContext private val appContext: Context       //I'm afraid that it may 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() {

}
英文:

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() {

}

答案1

得分: 3

ServiceTranslate 是一个具有比应用程序本身更长生命周期的 Service 类。

我认为这个说法不正确。如果进程在运行,应用程序的实例应该始终存在,如果 Service 处于活动状态,这就是情况。除非您将 Service 运行在自己的进程中,否则使用 AppContext 应该是完全安全的,因为 Service 将始终与一个关联的 Application 相关联。您可以通过在 Application 的 onDestroy 中放置一个日志语句来验证这一点,并确认当应用程序在 UI 中变为后台而 Service 仍然处于活动状态时,它不会被调用。相关线程

或者,您可以通过在 Service 的 DI 图上公开 Service.getResources() 来完全避开这个问题。这样,您就不需要依赖于 Application Context。

英文:

> 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.

答案2

得分: 1

  1. 是的,当使用@ApplicationContext与Hilt一起使用时,您确实会获得您的应用程序类的一个实例,在您的情况下是UIApp

  2. 在Android中,应用程序上下文是一个单例,它在整个应用程序的生命周期内存在。在您的情况下,您正在注入应用程序上下文,由于它的生命周期与整个应用程序一样长,即使Service正在运行并且应用程序的活动已销毁,也不会导致崩溃。您的ServiceTranslate可以继续运行并且可以有效访问appContext

英文:
  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.

huangapple
  • 本文由 发表于 2023年5月25日 14:20:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76329418.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定