我解决了这个问题,在我的应用程序是这样的:
创建对象的AsyncTasks(这样你就可以检查它们是否正在进行中):
private AsyncTask<String, Void, String> releaseMP;
private AsyncTask<String, Void, String> setSource;
为准备调用创建的AsyncTask :现在
private class setSource extends AsyncTask<String, Void, String> {
@Override
protected synchronized String doInBackground(final String... urls) {
try {
mMediaPlayer.prepare();
} catch (final IllegalStateException e) {
e.printStackTrace();
return e.getMessage();
} catch (final IOException e) {
e.printStackTrace();
return e.getMessage();
} catch (final Exception e) {
e.printStackTrace();
return e.getMessage();
}
return null;
}
@Override
protected void onCancelled() {
if (setSource != null)
setSource = null;
// Send error to listener
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
releaseMP = new releaseMP().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
@Override
protected void onPostExecute(final String result) {
if (setSource != null)
setSource = null;
// Check for error result
if (result != null) {
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
}
}
@Override
protected void onPreExecute() {
}
}
您准备代码:
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mDuration = -1;
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(getContext(), mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
// mMediaPlayer.prepareAsync();
// we don't set the target state here either, but preserve the
// target state that was there before.
mCurrentState = STATE_PREPARING;
} catch (final IOException ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
} catch (final IllegalArgumentException ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
} catch (final Exception ex) {
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
}
setSource = new setSource().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
最后,当您需要关闭mediaPlayer时,您将在释放之前检查setSource对象以查看它是否正在准备。如果准备,你会取消的AsyncTask,并在的AsyncTask onCancelled,你会复位,发行对象:
public void release(final boolean cleartargetstate) {
if (mMediaPlayer != null) {
if (setSource != null) {
setSource.cancel(true);
} else {
releaseMP = new releaseMP().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
}
}
这是我releaseMP的AsyncTask(这只是重置并释放对象):
private class releaseMP extends AsyncTask<String, Void, String> {
@Override
protected synchronized String doInBackground(final String... urls) {
Log.i(MethodNameTest.className() + "." + MethodNameTest.methodName(), "called");
if (mMediaPlayer != null) {
// Release listeners to avoid leaked window crash
mMediaPlayer.setOnPreparedListener(null);
mMediaPlayer.setOnVideoSizeChangedListener(null);
mMediaPlayer.setOnCompletionListener(null);
mMediaPlayer.setOnErrorListener(null);
mMediaPlayer.setOnBufferingUpdateListener(null);
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
}
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
return null;
}
@Override
protected void onPostExecute(final String result) {
Log.i(MethodNameTest.className() + "." + MethodNameTest.methodName(), "called");
if (releaseMP != null)
releaseMP = null;
}
}
我想到了这一点,但我并不确定它会解决手头的问题。 MediaPlayer文档说:“重要的是要注意,准备状态是一种暂时状态,并且在MediaPlayer对象处于准备状态时调用具有副作用的任何方法的行为未定义。”所以问题仍然存在,我会在“准备”状态中调用release(),结果是未定义的。我怀疑,在我的同步准备(),MediaPlayer转向这种“准备”状态,并导致我收到的错误。 – hgm 2011-12-14 20:59:58