如何停止所有在后台运行的处理程序?

时间:2018-10-22 10:43:56

标签: java android-handler

我正在编写一个动态创建音频播放器的应用程序。通过按下按钮,我希望所有处理程序在调用它们时停止并重新启动。这些处理程序基本上负责更新音频播放器的搜索栏。搜索栏和播放按钮正在创建为线性布局,此线性布局正在添加到父线性布局中。这样,例如,如果我根据代码决定创建4个音频播放器,并且希望他们能够一起播放音频,则将创建4个linearlayout的循环放到一个循环中,然后将它们添加到父LinearLayout中。代码或多或少看起来像这样(这只是相关部分,而不是真正的代码...):

for (int i = 0; i < 4; i++)
{
    LinearLayout audioLayout = new LinearLayout(this);
    audioLayout.setOrientation(LinearLayout.HORIZONTAL);
    audioLayout.setPadding(20, 20, 20, 20);
    final Button btnAudioPlay = new Button(this);
    btnAudioPlay.setBackgroundResource(R.drawable.play);
    LinearLayout.LayoutParams playButtonParams = new LinearLayout.LayoutParams(50, 50);
    playButtonParams.setMargins(20, 0, 20, 0);
    audioLayout.addView(btnAudioPlay, playButtonParams);
    final SeekBar sbAudioPosition = new SeekBar(this);
    LinearLayout.LayoutParams seekbarParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    seekbarParams.setMargins(20, 0, 20, 0);
    audioLayout.addView(sbAudioPosition, seekbarParams);
    parentLayout.addView(audioLayout);

    final MediaPlayer mpAudio = MediaPlayer.create(this, Uri.fromFile(audFile));
    mpAudio.setLooping(false);
    mpAudio.seekTo(0);
    int totalTime = mpAudio.getDuration();
    sbAudioPosition.setMax(totalTime);
    sbAudioPosition.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
    {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
        {
            if (fromUser)
            {
                mpAudio.seekTo(progress);
                sbAudioPosition.setProgress(progress);
            }
        }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {}
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {}
    });

    mpAudio.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            btnAudioPlay.setBackgroundResource(R.drawable.play);
            sbAudioPosition.setProgress(0);
        }
    });

    btnAudioPlay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (!mpAudio.isPlaying()) {
                mpAudio.start();
                btnAudioPlay.setBackgroundResource(R.drawable.pause);

                final Handler handler = new Handler();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        sbAudioPosition.setMax((int) mpAudio.getDuration());
                        int currentPossition = mpAudio.getCurrentPosition();
                        sbAudioPosition.setProgress(currentPossition);
                        handler.postDelayed(this, 0);
                    }
                });
            }
            else {
                mpAudio.pause();
                btnAudioPlay.setBackgroundResource(R.drawable.play);
            }
        }
    });
}

当我按下一个按钮时,我正在更新视图,并且我希望所有处理程序都停止,但是并没有发生……我试图在onCreate Handler handler = null;之前声明。 (而不是最终的处理程序),然后在linearlayout中将其设置为新的并且可以使用,但是在按钮的方法中,我调用了handler.removeCallbacksAndMessages(null);而且没有用我也试图声明可运行对象并调用handler.removeCallbacks(runOnUiThread);,但是我的应用程序崩溃了...:(

该怎么办才能解决? 如果我希望一个音频播放停止当前的音频播放,可以吗?能解决我的问题吗?

很抱歉,谢谢您的帮助。 :)

1 个答案:

答案 0 :(得分:0)

您可以将Handler用作Activity的成员,例如:

private Handler mHandler = new Handler();
private Runnable mRunnable = new Runnable() {
                @Override
                public void run() {
                    sbAudioPosition.setMax((int) mpAudio.getDuration());
                    int currentPossition = mpAudio.getCurrentPosition();
                    sbAudioPosition.setProgress(currentPossition);
                    mHandler.post(this);
                }
            };

然后在执行mHandler时使用mHandler.postDelayed(runnable,delay)。然后,当您要全部删除它们时,可以致电mHandler.removeCallbacks(null);

注意:您可以删除以下特定的可运行对象:mHandler.removeCallbacks(mRunnable);