-3

I hope to dependency injection MediaRecorder object with Hilt in Android Studio.

But the Code A get the error 'lateinit' modifier is not allowed on properties of nullable types .

And the Code B get the error Dagger does not support injection into private fields .

The Code C can be compiled, but it's not what I need. I need to define mRecorder as nullable, so I can use mRecorder = null to release it.

How can I fix the Code A?

Code A

@HiltViewModel
class SoundViewModel @Inject constructor(): ViewModel()
{
    @Inject lateinit var mRecorder: MediaRecorder?

}

@InstallIn(SingletonComponent::class)
@Module
object ObjectModule {
    @Provides
    @Singleton
    fun provideMediaRecorder(): MediaRecorder {
        return  MediaRecorder()
    }
}

Code B

@HiltViewModel
class SoundViewModel @Inject constructor(): ViewModel()
{
    @Inject var mRecorder: MediaRecorder? =null

}

...

Code C

@HiltViewModel
class SoundViewModel @Inject constructor(): ViewModel()
{
    @Inject  lateinit  var mRecorder: MediaRecorder

}

...
HelloCW
  • 843
  • 22
  • 125
  • 310

1 Answers1

2

You can't do property injection if you don't have reference to your component/injector object. You may want to add the recorder as constructor parameter.

@HiltViewModel
class SoundViewModel @Inject constructor(private val recorder: MediaRecorder
): ViewModel()

Alternatively, if you really want to make your recorder nullable you can utilize Provider:

@HiltViewModel
class SoundViewModel @Inject constructor(private val recorderProvider: Provider<MediaRecorder>
): ViewModel(){

    private val recorder : MediaRecorder? = null

   init {
        recorder = recorderProvider.get() 
    }

}

For releasing your media recorder use mediaRecorder.release() function.

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
  • Thanks! what are differents between my Code C and your code `class SoundViewModel @Inject constructor(private val recorder: MediaRecorder...` ? – HelloCW Apr 19 '22 at 10:49
  • There are three types of injecton: constructor, field and method, you are using field injection in CodeC without having component to perform the field/prop injection. – Nikola Despotoski Apr 19 '22 at 10:52
  • Thanks! `class SoundViewModel @Inject constructor(private val recorder: MediaRecorder? ...` can be compiled. is it correct code? – HelloCW Apr 19 '22 at 11:06
  • And more, I can't understand fully what `You can't do property injection if you don't have reference to your component/injector object.` means, could you tell me? Thanks! – HelloCW Apr 19 '22 at 11:10
  • You code `private val recorder : MediaRecorder? = null` can't be compiled, does it shoud be `private var recorder : MediaRecorder? = null` ? – HelloCW Apr 19 '22 at 11:17