Jayy
Jayy

Reputation: 14728

HandlerThread.getLooper() blocks indefinitely

I am trying to learn how to run MediaPlayer in its own thread, using HandlerThread. But I'm failing at the very first step. I have spent 2 days painfully trying to understand threads in Java/Android and really need some help. (I have read countless examples and javadoc pages, both Java and Android) and am feeling extremely frustrated/stupid.

In the example below, getLooper() blocks indefinitely. I have no idea why. Please can someone show me how to modify the code below to fix this?

Also, an example on how to send a message that results in a method of MediaPlayer being called (asynchronously) would be extremely valuable, probably saving me a week.

Thank you

public class HandlerThreadExample {

    private MediaPlayerThread mMpThread;
    private Looper mMptLooper;
    private Handler mMptHandler;

    public HandlerThreadExample(){
        mMpThread = new MediaPlayerThread();
        mMpThread.start();
        mMptLooper = mMpThread.getLooper(); // everything freezes here
    }
    public void setMediaPlayerDataSource(Uri uri){
        // send message that calls mMediaPlayer.setDataSource(uri);
    }
    public void prepareMediaPlayer(){
        // send message that calls mMediaPlayer.prepare();
    }
    public void startMediaPlayer(){
        // send message that calls mMediaPlayer.start();
    }

    private class MediaPlayerThread extends HandlerThread {
        MediaPlayer mMediaPlayer;
        public MediaPlayerThread() {
            super("MediaPlayer Thread", HandlerThread.NORM_PRIORITY);
        }
        public void run (){
            mMediaPlayer = new MediaPlayer();
        }
    }
}

Upvotes: 2

Views: 1221

Answers (2)

ben75
ben75

Reputation: 28706

From the javadoc of HandlerThread.getLooper() :

If this thread has been started, this method will block until the looper has been initialized.

To initialize the looper you need to call Looper.prepare() from the thread of the looper (i.e. it means from the run() method)

So in your code do this :

private class MediaPlayerThread extends HandlerThread {
    MediaPlayer mMediaPlayer;
    public MediaPlayerThread() {
        super("MediaPlayer Thread", HandlerThread.NORM_PRIORITY);
    }
    public void run (){
        Looper.prepare();
        mMediaPlayer = new MediaPlayer();
    }
}

As mentioned by @eldjon : calling super.run() will do this for you.

Upvotes: 0

eldjon
eldjon

Reputation: 2840

on the MediaPlayerThread you need to call the super method for run:

public void run (){
    mMediaPlayer = new MediaPlayer();
    super.run();
}

Important things are executed in its parent class run method. More specifically the looper is created and if you call getLooper() and looper is not created it will wait for its creation.

Upvotes: 3

Related Questions