patternjavaMinor
Sound manager for Android
Viewed 0 times
managersoundforandroid
Problem
I created a singleton class for managing sound effects on Android. This class will only be instanced and loaded once at the beginning, and each activity will use the loaded songs.
I don't know either if this is the good approach for Singleton, nor if this is the good way to play sounds in Android. This is working like a charm, and I'm wondering about the resource utilizations.
```
public class SoundManager {
private static SoundManager mInstance;
private SoundPool mSoundPool;
private HashMap mSoundPoolMap;
private Vector mAvailibleSounds = new Vector();
private Vector mKillSoundQueue = new Vector();
private Handler mHandler = new Handler();
private boolean mMuted = false;
private static final int MAX_STREAMS = 2;
private static final int KILL_AFTER = 3000;
public static final int SOUND_SELECT = 0;
public static final int SOUND_LOCKED = 1;
@SuppressLint("UseSparseArrays")
private SoundManager(Context context) {
mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap();
loadSounds(context);
}
public static SoundManager getInstance(Context context){
if(mInstance == null){
mInstance = new SoundManager(context);
Log.d("SPARTA", "Instanciation");
}
return mInstance;
}
/**
* Load all sounds and put them in their respective keys.
* @param context
*/
private void loadSounds(Context context){
addSound(context, SOUND_SELECT, R.raw.metallic_knock);
addSound(context, SOUND_LOCKED, R.raw.licorice);
}
/**
* Put the sounds to their correspondig keys in sound pool.
* @param context
* @param key
* @param soundID
*/
public void addSound(Context context, int key, int soundID) {
mAvailibleSounds.add(key);
mSoundPoolMap.put(key, mSoundPool.load(context, soundID, 1));
}
/**
* Find sound with the key and
I don't know either if this is the good approach for Singleton, nor if this is the good way to play sounds in Android. This is working like a charm, and I'm wondering about the resource utilizations.
```
public class SoundManager {
private static SoundManager mInstance;
private SoundPool mSoundPool;
private HashMap mSoundPoolMap;
private Vector mAvailibleSounds = new Vector();
private Vector mKillSoundQueue = new Vector();
private Handler mHandler = new Handler();
private boolean mMuted = false;
private static final int MAX_STREAMS = 2;
private static final int KILL_AFTER = 3000;
public static final int SOUND_SELECT = 0;
public static final int SOUND_LOCKED = 1;
@SuppressLint("UseSparseArrays")
private SoundManager(Context context) {
mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap();
loadSounds(context);
}
public static SoundManager getInstance(Context context){
if(mInstance == null){
mInstance = new SoundManager(context);
Log.d("SPARTA", "Instanciation");
}
return mInstance;
}
/**
* Load all sounds and put them in their respective keys.
* @param context
*/
private void loadSounds(Context context){
addSound(context, SOUND_SELECT, R.raw.metallic_knock);
addSound(context, SOUND_LOCKED, R.raw.licorice);
}
/**
* Put the sounds to their correspondig keys in sound pool.
* @param context
* @param key
* @param soundID
*/
public void addSound(Context context, int key, int soundID) {
mAvailibleSounds.add(key);
mSoundPoolMap.put(key, mSoundPool.load(context, soundID, 1));
}
/**
* Find sound with the key and
Solution
Let me start by saying I have very limited Android experience. That said, I did look into the
Hope this helps!
SoundPool class a bit and have some questions/comments about your implementation:- If you aren't already aware of some of the reasons why people consider Singletons an anti-pattern, I suggest you do some research on the topic and make sure you're ok with the downsides.
- Your class, for the most part, seems to be wrapping a
SoundPoolwith a key value pair structure despiteSoundPoolalready being a key value pair structure. I would imagine you could do away with most of this class and just use theSoundPoolclass directly.
- If you don't want to use
SoundPooldirectly for some reason, why not at least use the soundId as a key? It already appears to be unique, and it's what the calling code probably wants anyway. If not, you may want to do some checking to make sure that duplicate keys aren't entered, or take the key assignment out of the hands of the caller and simply return an id as the result of theaddSoundfunction.
- Using both
mSoundPoolMapandmAvailibleSoundsmeans you have to manage keys in two locations which could lead to them getting out of sync or some confusion as to why there are two fields holding the same information. Using onlymSoundPoolMapwould be sufficient and avoid duplication. This highly voted question isn't quite the same, but it touches on a lot of good points why this kind of duplication can be bad.
Hope this helps!
Context
StackExchange Code Review Q#45751, answer score: 8
Revisions (0)
No revisions yet.