2

我正在尝试学习如何使用 HandlerThread 在自己的线程中运行 MediaPlayer。但我在第一步就失败了。我花了 2 天的时间痛苦地尝试理解 Java/Android 中的线程,并且真的需要一些帮助。(我已经阅读了无数的示例和 javadoc 页面,包括 Java 和 Android)并且我感到非常沮丧/愚蠢。

在下面的示例中,getLooper() 无限期地阻塞。我不知道为什么。请有人告诉我如何修改下面的代码来解决这个问题?

此外,关于如何发送导致 MediaPlayer 方法被调用(异步)的消息的示例将非常有价值,可能会为我节省一周的时间。

谢谢

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();
        }
    }
}
4

2 回答 2

1

在 MediaPlayerThread 上,您需要调用 super 方法进行运行:

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

重要的事情在其父类的run方法中执行。更具体地说,looper 被创建,如果你调用 getLooper() 并且 looper 没有被创建,它将等待它的创建。

于 2014-08-02T09:38:28.380 回答
0

从 HandlerThread.getLooper() 的javadoc:

如果这个线程已经启动,这个方法会一直阻塞直到looper被初始化。

要初始化 looper,您需要从 looper 的线程调用Looper.prepare() (即它意味着来自 run() 方法)

所以在你的代码中这样做:

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

正如@eldjon 所提到的:打电话super.run()会为你做这件事。

于 2014-08-02T09:41:38.687 回答