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

2ledvvac  于 2023-05-27  发布在  Android
关注(0)|答案(1)|浏览(177)

bounty还有7天到期。此问题的答案有资格获得+50声望奖励。HelloCW正在寻找一个答案从一个有信誉的来源

我在Android Studio项目中使用Hilt作为DI。我知道 “ViewModel决不能引用视图、生命周期或任何可能包含活动上下文引用的类。"
因此,您可以发现图像A中有代码A的警告信息。
但是Hilt的ViewModelComponent绑定了Application,你可以看到article

**1:**我不知道为什么ViewModel中的private val appContext: Application不显示警告信息,是否意味着我使用Hilt时可以在ViewModel中使用Application?能告诉我吗?
**2:**顺便说一句,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()
{
     ...
}

图片A

j8ag8udp

j8ag8udp1#

这可能只是lint看到ViewModel()中的Context并抱怨它。因为你可能会给出一个生存期比ViewModel短的Context。

class MyViewModel: ViewModel() {
    //will complain about leaking context
    val ctx: Context = Context()
}

将使用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
)

对于2:Lint告诉你删除private瓦尔。因为你没有把它作为一个属性,所以瓦尔/var是不需要的。

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

如果你想使用它作为一个属性,你必须添加瓦尔/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")
    }
}

相关问题