【发布时间】:2015-03-17 19:33:31
【问题描述】:
在我的应用程序中,我在 RecyclerView 列表中有一堆 VideoView。当 Android SDK 中的 VideoView 从 MediaPlayer 接收到 onPrepared 回调时,它有时会崩溃。异常本身是在本机代码中触发的。这只是偶尔发生,我无法可靠地重现它。
Fatal Exception: java.lang.IllegalStateException
media.MediaPlayer.getVideoWidth (MediaPlayer.java)
android.widget.VideoView$2.onPrepared (VideoView.java:422)
android.media.MediaPlayer$EventHandler.handleMessage (MediaPlayer.java:2208)
android.os.Looper.loop (Looper.java:136)
android.app.ActivityThread.main (ActivityThread.java:5086)
java.lang.reflect.Method.invokeNative (Method.java)
在我看来,这是在 MediaPlayer 开始加载视频时引起的,然后在加载视频之前它以某种方式失效。尽管无效,onPrepared 仍然被调用,并且 VideoView 尝试访问视频宽度,导致异常。 VideoView.java 中的相关源代码为:
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mCurrentState = STATE_PREPARED;
// Get the capabilities of the player for this stream
Metadata data = mp.getMetadata(MediaPlayer.METADATA_ALL,
MediaPlayer.BYPASS_METADATA_FILTER);
if (data != null) {
mCanPause = !data.has(Metadata.PAUSE_AVAILABLE)
|| data.getBoolean(Metadata.PAUSE_AVAILABLE);
mCanSeekBack = !data.has(Metadata.SEEK_BACKWARD_AVAILABLE)
|| data.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE);
mCanSeekForward = !data.has(Metadata.SEEK_FORWARD_AVAILABLE)
|| data.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE);
} else {
mCanPause = mCanSeekBack = mCanSeekForward = true;
}
if (mOnPreparedListener != null) {
mOnPreparedListener.onPrepared(mMediaPlayer);
}
if (mMediaController != null) {
mMediaController.setEnabled(true);
}
mVideoWidth = mp.getVideoWidth();
mVideoHeight = mp.getVideoHeight();
int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be changed after seekTo() call
if (seekToPosition != 0) {
seekTo(seekToPosition);
}
... etc.
我试图通过仅在收到 onPrepared() 后调用 stopPlayback() 来修复它,但它没有帮助。
还有其他解决方案吗?
【问题讨论】: