MediaPlayer未经发布而最终确定

时间:2013-10-01 00:01:36

标签: android android-mediaplayer

我的应用似乎工作正常,但我收到MediaPlayer finalized without being released警告,我不知道为什么我会收到它们。奇怪的是,它们只在我使用MediaPlayer.create(ctxt, resid)播放资源文件(.ogg)时出现,而不是在我使用setDataSource(path)播放SD卡中的文件时显示。

我已经看了很多关于Stack Overflow的其他帖子,查看了开发人员文档,并尝试了不同的组合(太多不能列出),但似乎没有什么可以摆脱错误。不确定这是一个错误还是我正在做的事情。

我正在使用带有FragmentStatePagerAdapter的ViewPager,基本上,当你点击页面时它会播放声音。当您滑动到下一页时,它会停止播放声音(如果它仍在播放)。这是该部分的代码,但我在测试过程中删除了它并没有什么区别,但我想我会包含它以防万一:

public void stopAudioInFragment() {
    ViewPageFragment page = (ViewPageFragment)
            getSupportFragmentManager().findFragmentById(R.id.pager);
    if (page != null) {
        page.stopAudio();
    }
}

以下是片段的相关代码:

public static MediaPlayer mPlayer;
private int mAudioId;
private boolean mIsAudioFile = false;

public void playAudio() {
    // Setup media player to play audio
    mIsAudioFile = false;

    stopAudio();
    mPlayer = new MediaPlayer();

    if (!mIsAudioFile && mAudioId != -1 && mPlayer != null) {
        // Play local resource audio
        mPlayer = MediaPlayer.create(mContext, mAudioId);
        mPlayer.setOnCompletionListener(new OnCompletionListener() {

            public void onCompletion(MediaPlayer mp) {
                stopAudio();
            }
        });

    } else if (mAudioId != -1 && mPlayer != null) {
        // Play audio file on SD card
        try {
            mPlayer.setDataSource(audio_file_path);
            mPlayer.setOnCompletionListener(new OnCompletionListener() {

                public void onCompletion(MediaPlayer mp) {
                    stopAudio();
                }
            });

        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            mPlayer.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    mPlayer.start();
}

public void stopAudio() {
    if (mPlayer != null) {
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
        }
        mPlayer.reset(); // Might not be necessary, since release() is called right after, but it doesn't seem to hurt/cause issues
        mPlayer.release();
        mPlayer = null;
    }
}


@Override
public void onDestroy() {
    stopAudio();
    super.onDestroy();
}

同样,上述工作正常,似乎没有引起任何问题。如果我在一个页面上并多次点击它,它会开始播放声音然后停止/播放每个新的点击。它看起来像是在它破坏页面然后GC运行时出现的警告。每次播放音频文件时都会有一个警告。

我想知道为什么我只在播放资源文件而不是从SD卡播放文件时才会收到MediaPlayer finalized without being released警告。据我所知,它应该始终在GC之前完成。有什么想法吗?

更新:我做了一些测试,试着看看我是否可以查明任何“奇怪”的事情,但我唯一能看到的是它只会影响资源中的文件/ raw文件夹。这是我可以添加的内容:

  • 生成警告的文件位于res / raw文件夹中。
  • 如果我将文件(.ogg并使用.wav测试)移动到assets文件夹并从那里播放, MediaPlayer不会生成任何警告。
  • 我用.mp3,.wav和.mp4替换了res / raw中的一些文件 音频文件和所有生成的警告,就像原始文件一样 .ogg文件确实。
  • 我成功播放了来自SD卡的.mp3,.wav和.mp4文件,但他们没有 生成MediaPlayer警告。
  • 澄清:所有文件都正确播放,没有任何问题 用户观点。我想弄清楚的是为什么 MediaPlayer为res / raw中的音频文件生成警告。

看起来问题与MediaPlayer如何处理res / raw文件夹中的资源有关,但我不知道“问题”是什么或为什么它会生成MediaPlayer警告。

1 个答案:

答案 0 :(得分:1)

mp.release();无法使用时释放媒体播放器。 它会解决你的问题。

对于前。

mp.setOnCompletionListener(new OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {    
        mp.release();
    }
});