8

What's currently happening with my android application:

I mapped a simple image to a button and have it play a sound on click. On each click, I create a MediaPlayer object with a sound file in my raw folder, I set an OnClickListener for that MediaPlayer object which stops playing the file and releases it, and then I play the MediaPlayer object.

The code for the defined section:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    ImageButton start = (ImageButton) findViewById(R.id.imageButton1);
    start.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            MediaPlayer play = MediaPlayer.create(MainActivity.this, R.raw.dvno);
            play.setOnCompletionListener(new OnCompletionListener() {
                public void onCompletion(MediaPlayer mp) {
                    mp.stop();
                    mp.release();
                    mp = null;
                }
            });
            play.start();
        }
    });
}

What's wrong with it:

It works fine and does not crash, but it's terrible for memory and very slow in general. I'd like for users to click the button many times in a row, as fast as they possibly can, and hear the sound play instantaneously over and over with overlap. Creating a new MediaPlayer object on each click and waiting for it to finish and be released consumes too many resources and the sound often lags behind the actual press of the button. I'd like to be able to create a single sound as MediaPlayer object which can be played while overlapping on itself.

Possible Solution:

Create a single final MediaPlayer object in the scope of onCreate rather than onClick and somehow use threading to start the MediaPlayer object on every click. I read that this might be a possible solution, but I haven't ever used threads before and I don't know if they're slow, if not slower, than my current code, so I'd like to know if there's a solution without using threads that might be simpler. Manipulating the state of a single MediaPlayer to overlap on itself seems impossible at this point, but maybe I'm wrong.

Would this crash the program because of illegal states? If not, is this going to be slower than I want it to be? And if not, can anyone suggest a fix to my code?

Andro Selva
  • 53,910
  • 52
  • 193
  • 240
Maharlikans
  • 195
  • 2
  • 8
  • 1
    I think a SoundPool would really be more appropriate here based on your requirements. A MediaPlayer is a very heavy, high latency object generally used for playing videos and long music tracks. SoundPool is intended for saving short clips that will be played rapidly, overlapping, with low latency. The clip is initialized once, and then you just call play every time you want to play the sound. The only restriction I believe is that the uncompressed sound has to be less than 1MB, though I'm not positive. – Tim Oct 22 '12 at 05:44

1 Answers1

7

I suggest you use a SoundPool instead of MediaPlayer for this. Tutorial is here

Raimo Ihle
  • 302
  • 1
  • 3
  • I took your advice and ended up switching to SoundPool. Definitely easier, much more manageable, and faster. Although, in the emulator, the sound is slightly choppy towards the end of the short clip. It might just be the emulator. – Maharlikans Oct 23 '12 at 15:51
  • +1 worked for me where the crappy media player failed (by skipping and clipping the audio file) – Dori Mar 29 '13 at 21:03
  • sound pool is working fine but issue with the sound.it generates very low volume.how to increase the volume? – Rajesh Jan 29 '20 at 12:41