40

I'm using Hilt to inject context and other dependencies into my HomeViewModel class; Everything is working properly but I'm getting this warning. How can I prevent from leakings?

This is my HomeFragment (where I inject and use the HomeViewModel class):

@AndroidEntryPoint
class HomeFragment : Fragment() {

private val viewModel: HomeViewModel by viewModels()

....

}

This is the warning:

Hilt injection viewModel

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

I'm using:

//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"

Thanks!

-- Edited, as suggested, after the first given answer:

The Home Fragment now is:

enter image description here

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

}

Dependencies updated to:

//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"

And I'm still getting this leaking error.

Any ideias?

Tarsila Costalonga
  • 924
  • 2
  • 11
  • 21
  • 1
    If you need context why not just use `AndroidViewModel`? not sure about HILT leak though . – ADM Feb 16 '21 at 04:28
  • If you post images of code, please also copy/paste or type the actual code directly into the post. Please see [Why may I not upload images of code on SO when asking a question?](//meta.stackoverflow.com/a/285557/208273). Posts in which essential text is only included in images are likely to be closed for not having enough details. – Ryan M Feb 16 '21 at 19:13
  • Were you able to find a solution to this? I'm running into the same issue and I've tried updating the dependencies to the latest versions, but to no avail. – Walter Berggren Apr 27 '21 at 11:28
  • 1
    No, @WalterBerggren, I wasnt able. But I think you use this way is not a problem at all, check the last answer given to this post. The fellow made a test and assured this is no leak of memory and this is just a warning. – Tarsila Costalonga May 01 '21 at 12:44

6 Answers6

21

After I faced that warning

enter image description here

I decided to profile memory to be guaranteed that the approach causes a memory leak, but what I found is quite interesting

enter image description here

yeah, there is no leak it's just a warning so don't care about it anymore, happy coding ;)

Mostafa Anter
  • 3,445
  • 24
  • 26
  • 2
    I reached the same conclusion (I can't say for sure but since the app context will always outlive the activity context, there should be no leak) – frankelot Nov 30 '21 at 23:46
7

Inject application instead:

@Inject constructor(private val application: Application)

Then you can get the app context like this:

application.applicationContext
Unes
  • 312
  • 7
  • 12
6

I don't get this warning, and I inject a context the same way.

Try updating to 2.31.2-alpha for hilt and 1.0.0-alpha03 for hilt-androidx

There are a few breaking changes. You will need to annotate your view models with @HiltViewModel, use @Inject instead of @ViewModelInject. And you will need to replace any references to ApplicationComponent with SingletonComponent.

mikeBlack
  • 589
  • 5
  • 5
2

Your Kotlin plugin version is 1.4.30-release-Studio4.1-1?

If so, downgrade kotlin plugin version.

In 1.4.30-release-Studio4.1-1 version,

if viewmodel has context as instance variable, it causes warning.

inkwon
  • 39
  • 4
0

I had the same problem after updating Hilt dependencies.

It's right to use @HiltViewModel with @Inject before the constructor.

Regarding the leak due to the Context, just remove it from the ViewModel constructor, and pass the Context as method parameter of your functions, like this:

@HiltViewModel
class HomeViewModel @Inject constructor(
    private val locationDetailsAPI: LocationAPI,
    private val imagesAPI: ImagesAPI
) : ViewModel() { 

    fun getImages(context: Context) {
        // do something
    }
}
Dario Brux
  • 1,871
  • 1
  • 17
  • 15
  • Is passing it in the method parameter the right way? – Abhishek AN Mar 15 '21 at 10:45
  • 1
    I think this is not the best MVVM+Repository with Hilt practice with Context. Maybe there are other ways to use it better, or maybe not, I honestly don't know. But on second thought, using Context in this way you will avoid all memory leaks due to the Context because, always, the reference to the Context is destroyed after the method ends and GC is triggered. – Dario Brux Mar 15 '21 at 16:37
0

it should be safe here, There isn't really a leak here in the context constructor, it is just the lint check doesn't know that is the application context, and not some other context. and I think I think it'd be safe to suppress that warning too. to inspect the memory memory usage with Memory Profiler, read this documentation: https://developer.android.com/studio/profile/memory-profiler

Mado
  • 329
  • 3
  • 16