详细说明单例注意事项:
注意:这里也解决了连续创建一系列播放器(比如 20 个 mediaPlayers)时 Audioservice 失败的问题。
创建播放器:单例类应该创建另一个线程来处理媒体播放器操作(不是主 UI 线程)
Create Player Runnable:这个线程(由单例实例创建的应该被赋予后台优先级,在创建逻辑之前延迟“Thread.sleep(500);”以允许 MediaPlayer.create() 使用的 AudioService- 完成其工作,因为后一种方法立即返回。
创建 Player Runnable 代码:
/**
* 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();
}
}
}