为什么在Android Studio中使用Hilt可以在ViewModel中引用Application?

Hel*_*oCW 5 android android-viewmodel dagger-hilt

我在 Android Studio 项目中使用 Hilt 作为 DI。我知道“ViewModel 绝不能引用视图、生命周期或任何可能保存对活动上下文的引用的类”。

所以可以发现A图中对于Code A有一条警告信息。

不过ViewModelComponentHilt的已经绑定了Application,你可以看看这篇文章

1: 我不知道为什么 private val appContext: Application在ViewModel中不显示警告信息,是否意味着我在使用Hilt时可以使用Applicationin ?ViewModel你可以告诉我吗?

2: BTW,private val appContext: Application显示以下信息,为什么?

构造函数参数从不用作属性

代码A

@HiltViewModel
class RecordSoundViewModel @Inject constructor(
    @ApplicationContext private val myContext: Context,    //Android Studio displays warning information
    private val appContext: Application,                   // Why doesn't it dsiplay warning information
    private val savedStateHandle: SavedStateHandle
): ViewModel()
{
     ...
}
Run Code Online (Sandbox Code Playgroud)

图片A 在此输入图像描述

Via*_*ann 2

这可能只是 lint 在 ViewModel() 中看到 Context 并抱怨它。因为您提供的 Context 的生命周期可能比 ViewModel 短。

class MyViewModel: ViewModel() {
    //will complain about leaking context
    val ctx: Context = Context()
}
Run Code Online (Sandbox Code Playgroud)

将使用 ApplicationContext 的内容注入 ViewModel 是一个有效的用例。

@Module
@InstallIn(SingletonComponent::class)
object WorkManagerModule {

    @Provides
    @Singleton
    fun provideWorkManager(@ApplicationContext context: Context): WorkManager {
        return WorkManager.getInstance(context)
    }
}

@HiltViewModel
class MyViewModel @Inject constructor(
    val workManager: WorkManager
)
Run Code Online (Sandbox Code Playgroud)

对于 2:Lint 告诉您删除私有 val。由于您不将其用作属性,因此不需要 val/var 。

@HiltViewModel
class MyViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle
) {
    //not complaints about property
    val myId = savedStateHandle.get<String>("MyId")
}
Run Code Online (Sandbox Code Playgroud)

如果您想将其用作属性,则必须添加 val/var。

@HiltViewModel
class MyViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle
) {
    fun getMyIdFromSaveState(): String? {
        //will complain that it does not know savedStateHandle, you must add val or var.
        return savedStateHandle.get<String>("MyId")
    }
}
Run Code Online (Sandbox Code Playgroud)