【问题标题】:Inject context with Hilt: this field leaks a context object使用 Hilt 注入上下文:此字段泄漏上下文对象
【发布时间】:2021-05-18 20:38:07
【问题描述】:

我正在使用 Hilt 将上下文和其他依赖项注入到我的 HomeViewModel 类中;一切正常,但我收到此警告。 如何防止泄漏?

这是我的 HomeFragment(我在其中注入和使用 HomeViewModel 类):

@AndroidEntryPoint
class HomeFragment : Fragment() {

private val viewModel: HomeViewModel by viewModels()

....

}

这是警告:

class HomeViewModel @ViewModelInject constructor(
    @ApplicationContext val context: Context,
    private val locationAPI: LocationAPI,
    private val imagesAPI: ImagesAPI
) :
    ViewModel() {
...
}

我正在使用:

//Hilt DI
implementation "com.google.dagger:hilt-android:2.30.1-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.30.1-alpha"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02"
kapt "androidx.hilt:hilt-compiler:1.0.0-alpha02"

谢谢!

-- 按照建议在第一个给出的答案之后进行编辑:

首页片段现在是:

@HiltViewModel
class DetailsViewModel @Inject constructor(
    @ApplicationContext val context: Context,
    private val locationDetailsAPI: LocationAPI) :
    ViewModel() {
...

}

依赖更新为:

//Hilt DI
implementation "com.google.dagger:hilt-android:2.31-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.30.1-alpha"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0-alpha03"

我仍然遇到这个泄漏错误。

有什么想法吗?

【问题讨论】:

  • 如果您需要上下文,为什么不直接使用AndroidViewModel?虽然不确定 HILT 泄漏。
  • 如果您发布代码图片,也请复制/粘贴或直接在帖子中输入实际代码。请参阅Why may I not upload images of code on SO when asking a question?。仅在图片中包含基本文本的帖子可能会因为没有足够的细节而被关闭。
  • 您能找到解决方案吗?我遇到了同样的问题,我尝试将依赖项更新到最新版本,但无济于事。
  • 不,@WalterBerggren,我做不到。但是我认为您使用这种方式根本不是问题,请查看该帖子的最后一个答案。那家伙做了一个测试,并保证这不是内存泄漏,这只是一个警告。

标签: android kotlin dagger-hilt


【解决方案1】:

在我遇到那个警告之后

我决定分析内存以保证该方法会导致内存泄漏,但我发现非常有趣

是的,没有泄漏这只是一个警告,所以不要再关心它了,快乐编码;)

【讨论】:

  • 我得出了同样的结论(我不能肯定地说,但由于应用程序上下文总是比活动上下文长,所以应该没有泄漏)
【解决方案2】:

我没有收到此警告,我以相同的方式注入上下文。

尝试更新到 2.31.2-alpha 的 hilt 和 1.0.0-alpha03 的 hilt-androidx

有一些重大变化。您需要使用@HiltViewModel 注释您的视图模型,使用@Inject 而不是@ViewModelInject。您需要将所有对 ApplicationComponent 的引用替换为 SingletonComponent。

【讨论】:

  • 您好,我已经更新了依赖项并更改了代码,但仍然收到警告。关于我缺少什么的任何想法?
  • 很奇怪。确保您已将 hilt-android-gradle-plugin 更新为 2.31.2-alpha ...。此外,请检查 Android Studio 是否有更新。我正在运行 4.1.2
  • 我也在运行 AS 4.2,hilt 版本是 2.33-beta。警告仍然出现在我身上。
【解决方案3】:

您的 Kotlin 插件版本是 1.4.30-release-Studio4.1-1?

如果是这样,请降级 kotlin 插件版本。

在 1.4.30-release-Studio4.1-1 版本中,

如果 viewmodel 将上下文作为实例变量,则会导致警告。

【讨论】:

    【解决方案4】:

    更新 Hilt 依赖项后我遇到了同样的问题。

    在构造函数之前使用@HiltViewModel@Inject是对的。

    关于由于 Context 导致的泄漏,只需将其从 ViewModel 构造函数中删除,并将 Context 作为函数的方法参数传递,如下所示:

    @HiltViewModel
    class HomeViewModel @Inject constructor(
        private val locationDetailsAPI: LocationAPI,
        private val imagesAPI: ImagesAPI
    ) : ViewModel() { 
    
        fun getImages(context: Context) {
            // do something
        }
    }
    

    【讨论】:

    • 在方法参数中传递是否正确?
    • 我认为这不是最好的 MVVM+Repository with Hilt 实践 with Context。也许还有其他方法可以更好地使用它,或者可能没有,我真的不知道。但是再想一想,以这种方式使用 Context 可以避免由于 Context 导致的所有内存泄漏,因为对 Context 的引用总是在方法结束并触发 GC 后被销毁。
    【解决方案5】:

    改为注入应用程序:

    @Inject constructor(private val application: Application)
    

    然后你可以像这样得到上下文:

    application.applicationContext
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 2021-11-14
      • 2016-01-05
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多