【问题标题】:Android: Why i am not able to play sound on button click after some clicks?Android:为什么在单击某些按钮后我无法在按钮单击时播放声音?
【发布时间】:2012-03-27 10:50:46
【问题描述】:

如果用户单击按钮然后播放声音,我已经这样做了。但是现在我在点击几下后无法听到声音。不知道为什么?

这是我用来播放声音的代码。

代码:

case R.id.lockView:
        playSound(R.raw.dooropen);
        break;
    }

public void playSound(int resources){
    boolean mStartPlaying = true;
    if (mStartPlaying==true){
        mPlayer = new MediaPlayer();
        Uri uri = Uri.parse("android.resource://com.project.iMystick/" + resources);
        try{
            mPlayer.setDataSource(getApplicationContext(),uri);
            mPlayer.prepare();
            mPlayer.start();
        } 
        catch (IOException e){
            Log.e(LOG_TAG, "prepare() failed");
        }
    } 
    else{
       //   stopPlaying();
        //rePlay.setText("Replay");
        mPlayer.release();
        mPlayer = null;
    }
    mStartPlaying = !mStartPlaying;
}

点击几下后,我在 logcat 中收到了这种类型的错误消息:

日志:

03-27 16:15:02.737: ERROR/MediaPlayer(1057): Error (-19,0)
03-27 16:15:03.858: DEBUG/AudioSink(34): bufferCount (4) is too small and increased to 12
03-27 16:15:03.858: ERROR/AudioFlinger(34): not enough memory for AudioTrack size=32832
03-27 16:15:03.858: DEBUG/MemoryDealer(34):   AudioTrack (0x12abf8, size=1048576)
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     0: 0012ac10 | 0x00000000 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     1: 0012aca0 | 0x00008040 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     2: 0012b5a8 | 0x00010080 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     3: 0012bec8 | 0x000180C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     4: 0012c7f0 | 0x00020100 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     5: 0012d1f0 | 0x00028140 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     6: 0012db20 | 0x00030180 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     7: 00136448 | 0x000381C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     8: 0013ee00 | 0x00040200 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):     9: 0000de10 | 0x00048240 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    10: 0012b708 | 0x00050280 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    11: 00022c70 | 0x000582C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    12: 000234c0 | 0x00060300 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    13: 00115e38 | 0x00068340 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    14: 00117a80 | 0x00070380 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    15: 00118798 | 0x000783C0 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    16: 00042228 | 0x00080400 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    17: 0004bd48 | 0x00088440 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    18: 00055998 | 0x00090480 | 0x00008040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    19: 0005f5f0 | 0x000984C0 | 0x00003040 | A 
03-27 16:15:03.858: DEBUG/MemoryDealer(34):    20: 000712b0 | 0x0009B500 | 0x00008040 | A
03-27 16:15:03.867: ERROR/AudioTrack(34): AudioFlinger could not create track, status: -12
03-27 16:15:03.867: ERROR/AudioSink(34): Unable to create audio track
03-27 16:15:03.877: ERROR/MediaPlayer(1057): error (-19, 0)

enter code here

【问题讨论】:

    标签: android audio android-ndk media-player


    【解决方案1】:

    您需要 release() 媒体播放器,否则资源不会被释放,并且您很快就会耗尽内存(因为您下次再次分配它们)。 所以,我认为你可以玩两次甚至三次......但不释放资源就不能玩很多次

    建议一旦不再使用 MediaPlayer 对象,立即调用 release() 以便与 MediaPlayer 对象关联的内部播放器引擎使用的资源可以立即释放。资源可能包括单例资源,例如硬件加速组件,调用 release() 失败可能会导致 MediaPlayer 对象的后续实例回退到软件实现或完全失败。See this link

    【讨论】:

      【解决方案2】:

      MediaPlayer 并非按照您尝试使用它的方式设计。这就是您面临问题的原因。

      MediaPlayer `不是一个好的选择当您播放小音效时,因为用户可以很快点击多个按钮,您必须为所有这些按钮创建一个 MP 对象t 同步发生,并且在您单击按钮时立即发生。选择 SoundPool 类,它允许您将较小的声音加载到内存中,并且您可以随时播放它们,而不会像在媒体播放器中感觉到任何延迟。 http://developer.android.com/reference/android/media/SoundPool.html这是一个不错的教程:http://www.anddev.org/using_soundpool_instead_of_mediaplayer-t3115.html

      【讨论】:

      • 如果可以,请使用 soundPool。多个 MediaPlayer 实例将在处理能力较低的手机上开始滞后。我遇到了这个问题,不得不切换到 SoundPool
      【解决方案3】:

      我认为问题在于您没有等到第一个完成(或停止)才开始第二个.. 尝试在完成时收听上一个然后启动下一个..您可以使用 setOnCompletionListener。

      类似问题: android playing two songs problem

      代码:

          package ooo.iii;
      
          import java.io.IOException;
      
      
          import android.app.Activity;
          import android.media.MediaPlayer;
          import android.net.Uri;
          import android.os.Bundle;
          import android.util.Log;
          import android.view.View;
          import android.view.View.OnClickListener;
          import android.widget.Button;
      
          public class Test_audioActivity extends Activity { 
              /** Called when the activity is first created. */
              Button btn;
              @Override
              public void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
          //        setContentView(R.layout.main); 
                  setContentView(R.layout.main);
                  btn=(Button)findViewById(R.id.ss);
      
                  btn.setOnClickListener(new OnClickListener() { 
      
                      @Override
                      public void onClick(View v) {
                          playSound(R.raw.musi);
      
                      }
                  });
      
              }
      
      
      
          public void playSound(int resources){
              try{
              boolean mStartPlaying = true;
              MediaPlayer  mPlayer=null;
          if (mStartPlaying==true){
      
                mPlayer = new MediaPlayer();
              Uri uri = Uri.parse("android.resource://ooo.iii/" + resources);
      
                  mPlayer.setDataSource(getApplicationContext(),uri);
                  mPlayer.prepare();
                  mPlayer.start();
      
          } 
          else{
             //   stopPlaying();
              //rePlay.setText("Replay");
              mPlayer.release();
              mPlayer = null;
          }
          mStartPlaying = !mStartPlaying;
      
      
          } 
          catch (IOException e){
              Log.e("ERR", "prepare() failed");
          }
          }
      
      
      
      }
      

      你需要改变:

      1- source @ res/raw/musi .. 给你的

      2- res/layout/main.xml 中按钮的 id 从 ss 到你的 ..

      3- Uri uri = Uri.parse("android.resource://ooo.iii/" + resources);把包名改成你的

      仅此而已..我在真实设备上进行了测试并单击了很多次并获得了比以前仍在播放的新声音

      【讨论】:

      • 我明白你的意思,但如果想玩第二次,即使它没有停止呢?
      • 在这种情况下..使用另一个媒体播放器实例..关键是如果它忙于其他事情,请不要使用相同的对象..
      • ok 那么它对我有用吗?我的意思是,如果我连续点击同一个按钮,那么?
      • 我想是的,让它更容易,并将 mPlayer 作为局部变量而不是类成员实例 .. 这样任何时候你调用 playSound(..) 你都会使用另一个版本的变量...跨度>
      • 抱歉 RAJU .. 你错了我现在在我的设备上测试了它,它可以工作.. 代码正是我将作为更新包含在我的答案中......
      【解决方案4】:

      我遇到了同样的问题,我通过使用 OnCompletionListener 中的 release() 方法解决了它:

      MediaPlayer mp = MediaPlayer.create(getApplicationContext(), resource);
              mp.start();
              mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                  @Override
                  public void onCompletion(MediaPlayer mp) {
                      mp.release();
                  }
              });
      

      【讨论】:

        猜你喜欢
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 2016-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多