Issue
I'm trying to create a singleton class that will be responsible for playing game sounds. I created a singleton class GameSounds with a method playSound(). In the res folder I have a a subfolder 'raw' with a file letter_found.mp3.
This is the source code of the GameSounds class I wrote:
import android.app.Application;
import android.content.Context;
import android.media.MediaPlayer;
public class GameSounds extends Application {
private static GameSounds gameSounds = new GameSounds();
private static MediaPlayer soundPlayer;
private static Context mContext;
private static int mySoundId = R.raw.letter_found;
private GameSounds() {
mContext = this;
}
public static GameSounds getInstance() {
return gameSounds;
}
public static void playSound() {
soundPlayer = MediaPlayer.create(mContext, mySoundId);
soundPlayer.start();
}
}
This doesn't seem to work as I'm getting the following error message:
"java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference"
I don't understand why this is happening. I tried to search Stackoverflow but couldn't find a solution.
Any help/explanation is greatly appreciated.
Solution
You can have a Singleton holding an Application Context (NOT Activity context) but practically you have to set this context before you use your singleton which can be enforced by throwing exceptions. See below example code.
public class GameSounds {
private static Context sContext;
public static void setContext(Context context) {
if (context == null) {
throw new IllegalArgumentException("context cannot be null!");
}
// In order to avoid memory leak, you should use application context rather than the `activiy`
context = context.getApplicationContext();
if (context == null) {
throw new IllegalArgumentException("context cannot be null!");
}
sContext = context;
}
private static Context getContext() {
if (sContext != null) {
return (Context)sContext;
}
throw new IllegalStateException("sContext was not set yet! Please call method setContext(Context context) first.");
}
// the rest of other methods. e.g. playSounds()
private static GameSounds gameSounds = new GameSounds();
private GameSounds() {
}
public static GameSounds getInstance() {
return gameSounds;
}
public void playSound() {
Context context = getContext();
soundPlayer = MediaPlayer.create(context, mySoundId);
soundPlayer.start();
}
}
Answered By - shizhen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.