如何从线程中的Activity中开始播放音乐?

时间:2013-11-24 21:33:09

标签: android multithreading android-mediaplayer

我无法从线程中启动Activity中的MediaPlayer。 我在我的Android活动中加载了声音,称为Snakes,并从自定义View类播放...

Activity Snakes()...
    void playSound(int i){
        if (sounds != null){
            sounds.play(sound_questions[i], 1.0f, 1.0f, 0, 0, 1.0f);
        }
    }


CustomView()...
    ((Snakes)getContext()).playSound();

这很有效。

我在Activity类中通过MediaPlayer播放音乐。为了延迟启动,我想使用从游戏控制线程调用的mediaPlayer.Start()。我和声音播放一样接近它,并将它放在我的Activity类

中的一个简单方法中
    void startMusic(){
    mediaPlayer.start();
}

但是,我不能从线程中调用此方法。

我应该如何从线程中的活动中启动MediaPlayer?

1 个答案:

答案 0 :(得分:1)

在您的活动中放置一个消息处理程序。

public class MyActivity extends Activity {

    // Handler message constants
    public static final int PLAY_SOUND = 0;
    public static final int SOME_OTHER_MESSAGE = 1;
    ...

    private final MainHandler mMainHandler = new MainHandler(this);

    // Handler
    private static class MainHandler extends Handler {

        // Using a WeakReference is recommended to avoid memory leaks
        private final WeakReference<MainActivity> mActivity;
        public MainHandler(MainActivity activity) {
            mActivity = new WeakReference<MainActivity>(activity);
        }

        // The message handler
        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = mActivity.get();
            if (activity != null) {
                final int index;
                switch (msg.what) {
                case PLAY_SOUND:
                    activity.playMySound();
                    break;
                case SOME_OTHER_MESSAGE:
                    ...
                    break;
                ...
                }   
            }           
        }
    };

    private void playMySound() {
    ...
    }
}

获取对线程中处理程序的引用,并使用它向活动发送消息。

public class MyThread extends Thread {

    private Handler mParentHandler;

    // Constructor
    private MyThread(Handler parentHandler) {
        mParentHandler = parentHandler;
    }

    ...
    // When you want to start playback
    Message messageToMain = Message.obtain();
    messageToMain.what = MainActivity.PLAY_SOUND;
    mParentHandler.sendMessage(messageToMain);
    ...
}

或者,如果将主消息处理程序通过它的构造函数传递给线程不适合您的情况,则可以在线程中创建一个静态方法,以便在类级别将其传递给处理程序。

public class MyThread extends Thread {

    // make mHandler static so it can be defined at a class level.
    private static Handler mHandler;

    // Constructor
    private MyThread(...) {
        // no need to pass Handler in constructor now
    }

    // static method for setting mHandler
    public static void setHandler(Handler suppliedHandler) {
        mHandler = suppliedHandler;
    }

    ...
    // When you want to start playback
    Message messageToMain = Message.obtain();
    messageToMain.what = MainActivity.PLAY_SOUND;
    mHandler.sendMessage(messageToMain);
    ...
}

然后确保在创建线程的任何实例之前设置要使用的线程的处理程序(例如,在活动的onCreate()中执行此操作)。

public class MyActivity extends Activity {

    // Handler message constants
    public static final int PLAY_SOUND = 0;
    public static final int SOME_OTHER_MESSAGE = 1;
    ...

    private final MainHandler mMainHandler = new MainHandler(this);

    // Handler
    private static class MainHandler extends Handler {

        // Using a WeakReference is recommended to avoid memory leaks
        private final WeakReference<MainActivity> mActivity;
        public MainHandler(MainActivity activity) {
            mActivity = new WeakReference<MainActivity>(activity);
        }

        // The message handler
        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = mActivity.get();
            if (activity != null) {
                final int index;
                switch (msg.what) {
                case PLAY_SOUND:
                    activity.playMySound();
                    break;
                case SOME_OTHER_MESSAGE:
                    ...
                    break;
                ...
                }   
            }           
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
        MyThread.setHandler(mMainHandler);
        // setting this at a class level means all future instances of MyThread
        // will have their mHandler set to mMainHandler
        ...
    }

    private void playMySound() {
    ...
    }
}
相关问题