Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android MediaPlayer stuck in prepare()

I'm facing a serious problem with the Media Player(MP) being stuck at the prepare() method. My app runs prepare() in an AsyncTask to avoid blocking the UI, since the sources are from the web. There are several 'play' buttons that the user can click at any time, so I added the prepare() inside a synchronized method to better control the state of the MP. My app also call a release() onPause to free the used resources.

Thing is, I noticed that if release() is called while preparing, prepare() never returns, and so I'm stuck inside a synchronized method. The worst of it is that the AsyncTask thread is in a deadlock, and every time that the user click on play in that state another thread is wasted since it keeps waiting to acquire the monitor that is in possesion of the never-returning prepare(). Soon all my AsyncTasks threads are wasted and since I use them extensively, my app stops working.

So my question is: do anyone has an idea of how overcoming this problem? I'm seriously thinking of redoing all my work with the MediaPlayer, but I need to know the best way to handle situations like this one beforehand.

like image 574
hgm Avatar asked Dec 14 '11 20:12

hgm


2 Answers

You should use prepareAsync() instead. And you won't need AsyncTask just for the sake of MediaPlayer preparation.

like image 188
inazaruk Avatar answered Oct 17 '22 09:10

inazaruk


The problem with using Asyntasks or prepareAsync() for that matter is that it doesn't automatically switch the MediaPlayer's state to prepared. You would think it does, but for some reason it doesn't. I got stuck with this same problem for a few days until someone suggested me to implement the OnPreparedListener, and use that to use my MediaPlayer.

Adding it is quite simple.

First, implement the listener in your class: (I'm using this for a Service so yours will look slightly different.)

public class MusicService extends Service implements OnPreparedListener

Next, in your play / prepare statement, use prepareAsync, and set the listener.

mp.prepareAsync();
mp.setOnPreparedListener(this);

Next, add the onPrepared method and add your starting code:

public void onPrepared(MediaPlayer mediaplayer) {
        // We now have buffered enough to be able to play
        mp.start();
    }

That should do the trick.

like image 24
Sander van't Veer Avatar answered Oct 17 '22 08:10

Sander van't Veer