尝试使用MediaPlayer崩溃实现按钮单击声音

时间:2016-04-19 20:53:36

标签: android android-mediaplayer

我有一个自定义视图(一个按钮),我希望它在按下时有一定的声音。

private void playSound() {
    if (mediaPlayer == null)
        initMediaPlayer();

    try {
        if (mediaPlayer.isPlaying())
            mediaPlayer.stop();
        mediaPlayer.prepare();
        mediaPlayer.start();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
}

private void initMediaPlayer() {
    try {
        AssetFileDescriptor afd = getContext().getAssets().openFd("music/number_tap.m4a");
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

每次单击按钮时,我都会调用playSound方法。只要屏幕上只有一个按钮,它就可以正常工作。没问题。

如果我在屏幕上有更多按钮并按下第一个按钮几次(正常工作),然后按下其他按钮2次(第二次按下第二个按钮时崩溃),它会崩溃。

知道可能出现什么问题吗?这是崩溃堆栈跟踪。

  

致命的例外:主要                                                                             过程:com.matejhacin.multiflow,PID:20991                                                                             java.lang.IllegalStateException                                                                                 在android.media.MediaPlayer._prepare(本机方法)                                                                                 在android.media.MediaPlayer.prepare(MediaPlayer.java:1163)                                                                                 在com.matejhacin.multiflow.views.KeyButtonView.playSound(KeyButtonView.java:126)                                                                                 在com.matejhacin.multiflow.views.KeyButtonView.onTouch(KeyButtonView.java:77)

1 个答案:

答案 0 :(得分:2)

从我所看到的,你有自己的按钮KeyButtonView.java的实现,并且在那个类中你有mediaPlayer作为成员变量,所以当你有两个按钮时,分别有两个KeyButtonView类实例和两个mediaPlayer的实例。为什么不使用mediaPlayer的一个实例,让我们说你让它静态,并使playSound()和initMediaPlayer()方法同步和静态,这应该是一个快速而简单的改变,只是为了测试如果有问题。还有别的,你使用onTouch()来处理点击,为什么不尝试使用OnClickListener?如果你没有正确使用onTouch,你将在UI线程上结束一堆调用,并且每次在prepare()处阻塞,这都不好。解决此问题后,应考虑使用prepareAsync()和setOnPreparedListener()重写它。