I am using android media player class for playing notification sound in my android Application.
MediaPlayer player = MediaPlayer.create(getApplicationContext
You should consider the Singleton pattern. Make a class MyPlayer that has a static method getMediaPlayer()
that returns the same instance of MediaPlayer each time called.
I always do similar thing with a modified version of Singleton Pattern. Since context is needed everywhere in Android, I pass the context to the instance:
public class Asset{
public static Asset(Context context);
}
You can also have different singleton across different context scope, in this implementation, for example:
private static Hashtable<Context, Asset> instances;
public static Asset(Context context){
if (!instances.containKey(context)){
instances.put(context, new Asset(context));
return instances.get(context);
}
The advantage of this compare to classic singleton, is you can define the scope of your singletons. Sometimes you just need the instance stay in same Activity, but second Activity may have different instance. If you need it across different Activity, you just need to pass context.getApplicationContext().
Note: here, the problem of Audioservice failure when creating a series of players consecutively (say 20 mediaPlayers) is addressed too.
Creating the player: The singleton class should create another thread to handle the mediaplayer operations (not the main UI thread)
Create Player Runnable: This thread (created by the singleton instance should be given background priority, a delay of "Thread.sleep(500);" before creation logic to allow the AudioService- used by the MediaPlayer.create()- to finish its work since the later method returns instantly.
Create Player Runnable code:
/**
* Created by George hannuneh on 10/12/2015.
* Holds the background work for creating a media player
*/
public class CreatePlayerRunnable implements Runnable {
static final int CREATE_STATE_FAILED = -1;
static final int CREATE_STATE_STARTED= 0;
static final int CREATE_STATE_COMPLETED= 1;
private static final String TAG ="CreatePlayerRunnable";
private static int sRunnablesCount = 1;
final TaskRunnableCreatePlayerMethods mPlayerTask;
/**
*
* An interface that defines methods that PlayerCreationTask implements. An instance of
* CreatePlayerTask passes itself to an CreatePlayerRunnable instance through the
* CreatePlayerRunnable constructor, after which the two instances can access each other's
* variables.
*/
interface TaskRunnableCreatePlayerMethods {
/**
* Sets the Thread that this instance is running on
* @param currentThread the current Thread
*/
void setCreatePlayerThread(Thread currentThread);
Context getActivity();
Uri getMediaUri();
void handleCreationState(int createStateFailed);
void setPlayer(MediaPlayer returnMediaPlayer);
String getPlayerId();
MediaPlayer getPlayer();
}
/**
* This constructor creates an instance of CreatePlayerRunnable and stores in it a reference
* to the CreatePlayerTask instance that instantiated it.
*
* @param createPlayerTask The CreatePlayerTask
*/
CreatePlayerRunnable(TaskRunnableCreatePlayerMethods createPlayerTask) {
mPlayerTask = createPlayerTask;
}
@Override
public void run() {
/*
* Stores the current Thread in the CreatePlayerTask instance,
* so that the instance
* can interrupt the Thread.
*/
mPlayerTask.setCreatePlayerThread(Thread.currentThread());
// Moves the current Thread into the background
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
MediaPlayer returnMediaPlayer = null;
try {
Thread.sleep(500);
// Before continuing, checks to see that the Thread hasn't
// been interrupted
if (Thread.interrupted()) {
throw new InterruptedException();
}
returnMediaPlayer = MediaPlayer.create(mPlayerTask.getActivity(), mPlayerTask.getMediaUri());
if (returnMediaPlayer == null) {
Log.e("CreatePlayerRunnable", mPlayerTask.getMediaUri()+ " - failed to create player");
return;
}
PlayerEventsHandler playerEvents = new PlayerEventsHandler(mPlayerTask.getPlayerId());
returnMediaPlayer.setLooping(true);
returnMediaPlayer.setOnCompletionListener(playerEvents);
returnMediaPlayer.setOnErrorListener(playerEvents);
returnMediaPlayer.setVolume(0f, 0f);
returnMediaPlayer.start();
} catch (InterruptedException e1) {
// Does nothing
} catch(Exception e)
{
returnMediaPlayer = null;
e.printStackTrace();
}
finally {
if(MainActivity.DEBUG_MODE_ENABLED){
Log.d(TAG, "end of runnable: "+ sRunnablesCount++);
}
if (null == returnMediaPlayer){
mPlayerTask.handleCreationState(CREATE_STATE_FAILED);
} else {
mPlayerTask.setPlayer(returnMediaPlayer);
// Reports a status of "completed"
mPlayerTask.handleCreationState(CREATE_STATE_COMPLETED);
}
// Sets the current Thread to null, releasing its storage
mPlayerTask.setCreatePlayerThread(null);
// Clears the Thread's interrupt flag
Thread.interrupted();
}
}
}