package com.oyly.gpsdemo
import android.content.Context
import android.media.MediaPlayer
class SoundGenerator(context: Context) : MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener {
private var mediaPlayer: MediaPlayer = MediaPlayer()
private var nextSound: Int = R.raw.coast
init {
try { mediaPlayer = MediaPlayer.create(context, R.raw.coast) }
catch (ex : Exception) { println("lyseoy11: $ex") }
mediaPlayer.setOnPreparedListener(this)
mediaPlayer.setOnCompletionListener (this)
}
override fun onPrepared(p0: MediaPlayer) {mediaPlayer.start()}
override fun onCompletion(p0: MediaPlayer?) { playSound() }
fun queueSound(resid: Int) {
nextSound = resid
if (!mediaPlayer.isPlaying) playSound()
}
fun playSound() {
mediaPlayer.reset()
mediaPlayer.setDataSource(resources.openRawResourceFd(nextSound))
mediaPlayer.prepareAsync()
}
}
The "mediaPlayer = MediaPlayer.create(context, R.raw.coast" line throws the following exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
I have moved this code from a standalone app, where it worked, into this class of another app. Now it doesn't work and I can't understand why. The MediaPlayer.Create() method takes as arguments the context (which I pass on from the MainActivity class that calls this class), and an uri to the audio file to be played. Neither of them are null.
Why do I get this exception?
Edit:
The only place SoundGenerator is created is in the MainActivity Initializer:
class MainActivity : AppCompatActivity() {
private var soundGenerator : SoundGenerator = SoundGenerator(this)
...
}
CodePudding user response:
Often it is best to wait to use the activity as a context until later in the lifecycle when things have been set up (e.g. in onCreate
) to avoid initialization order issues. For exampe:
class MainActivity : AppCompatActivity() {
private lateinit var soundGenerator : SoundGenerator
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
soundGenerator = SoundGenerator(this)
}
}
Alternately, sometimes you can use applicationContext
instead of the current activity as an appropriate context.