线程不中断 [英] Thread not interrupting

查看:167
本文介绍了线程不中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习如何使用线程在Android中,要做到这一点,我做了一个小的应用程序播放了一系列的音符。我们的想法是,有一个启动按钮和结束按钮,并且(显然)如果preSS的起动按钮开始播放音乐,并且如果你preSS的结束按钮,它将停止。启动按钮工作得很好,但问题是,最终按钮没有。我无法弄清楚为什么,也许有些你能帮助我。这是code:

 公共类pressAndPlay延伸活动{
    私人挥发性主题initBkgdThread;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

        按钮startButton =(按钮)findViewById(R.id.trigger);
        startButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图查看){

                //创建线程
                initBkgdThread =新主题(新的Runnable(){
                    公共无效的run(){
                        播放音乐();
                    }
                });
                initBkgdThread.start();
            }
        });

        按钮endButton =(按钮)findViewById(R.id.end);
        endButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图查看){
                end_music();
            }
        });
    }

    INT []票据= {R.raw.c5,R.raw.b4,R.raw.a4,R.raw.g4};
    INT NOTE_DURATION = 400;
    MediaPlayer的m_mediaPlayer;

    私人无效play_music(){
        为(中间体二= 0; II蛋白酶12;ⅱ++){
            //检查,以确保主要活动未暂停
            如果(!暂停){
                如果(m_mediaPlayer!= NULL){m_mediaPlayer.release();}
                m_mediaPlayer = MediaPlayer.create(这一点,指出[II%4]);
                m_mediaPlayer.start();
                尝试 {
                    视频下载(NOTE_DURATION);
                }赶上(InterruptedException异常E){
                    e.printStackTrace();
                }
            }
        }
    }

    私人无效end_music(){
         如果(initBkgdThread!= NULL){
             initBkgdThread.interrupt();
             initBkgdThread = NULL;
         }
    }

    布尔暂停= FALSE;
    @覆盖
    保护无效的onPause(){
        暂停= TRUE;
        super.onPause();
    }
    @覆盖
    保护无效onResume(){
        super.onResume();
        暂停= FALSE;
    }
}
 

解决方案

正在调用中断()播放线程,但它可能是等待睡觉的时间。这将陷入睡眠抛出一个 InterruptedException的。您需要捕获了异常的的退出循环停止播放:

 尝试{
      视频下载(NOTE_DURATION);
  }赶上(InterruptedException异常E){
      // XXX需要停止在这里打球,也许回归或破裂?
      返回;
  }
 

由于中断()也可以得出在不同的时间,你需要测试中断状态,退出你的循环:

 如果(暂停和放大器;!&安培;!Thread.currentThread()isInterrupted()){
     ...
 

此外,这两个线程之间共享的所有变量要么需要为同步或标记挥发性。该暂停标志也许应该是挥发性这里:

 挥发性布尔暂停= FALSE
 

最后,留给后人,当你发现 InterruptedException的,它清除线程的中断状态。它通常是很好的做法,立即设置中断标志的线程上,以便其他人可以测试它:

 尝试{
      视频下载(NOTE_DURATION);
  }赶上(InterruptedException异常E){
      //重新建立中断条件
      Thread.currentThread.interrupt();
      ...
  }
 

I'm learning how to use threads in Android, and to do that I've made a small application that plays a series of notes. The idea is that there is a start button and an end button and that (obviously) if you press the start button it starts playing music, and if you press the end button, it stops. The start button works just fine, but the problem is that the end button doesn't. I'm having trouble figuring out why, so maybe some of you can help me out. This is the code:

public class PressAndPlay extends Activity {
    private volatile Thread initBkgdThread;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button startButton = (Button) findViewById(R.id.trigger);
        startButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {

                // create thread
                initBkgdThread = new Thread(new Runnable() {
                    public void run() {
                        play_music();
                    }
                });
                initBkgdThread.start();
            }
        });

        Button endButton = (Button) findViewById(R.id.end);
        endButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                end_music();
            }
        });
    }

    int[] notes = {R.raw.c5, R.raw.b4, R.raw.a4, R.raw.g4};
    int NOTE_DURATION = 400;
    MediaPlayer m_mediaPlayer;

    private void play_music() {
        for(int ii=0; ii<12; ii++) {
            //check to ensure main activity is not paused
            if(!paused) {
                if (m_mediaPlayer != null) {m_mediaPlayer.release();}
                m_mediaPlayer = MediaPlayer.create(this, notes[ii%4]);
                m_mediaPlayer.start();
                try {
                    Thread.sleep(NOTE_DURATION);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void end_music() {
         if(initBkgdThread != null) {
             initBkgdThread.interrupt();
             initBkgdThread = null;
         }
    }

    boolean paused = false;
    @Override
    protected void onPause() {
        paused = true;
        super.onPause();
    }
    @Override
    protected void onResume() {
        super.onResume();
        paused = false;
    }
}

解决方案

You are calling interrupt() on the playing thread but it is probably waiting in sleep at the time. This will caught sleep to throw a InterruptedException. You need to catch that exception and exit the loop to stop the playing:

  try {
      Thread.sleep(NOTE_DURATION);
  } catch (InterruptedException e) {
      // XXX need to stop playing here, maybe return or break?
      return;
  }

Since the interrupt() can also come at a different time, you need to test for interrupt status and quit your loop:

  if (!paused && !Thread.currentThread().isInterrupted()) {
     ...

Also, all variables that are shared between two threads either need to be synchronized or be marked volatile. The paused flag should probably be volatile here:

volatile boolean paused = false

Lastly, for posterity, when you catch InterruptedException, it clears the interrupt status of the thread. It is usually good practice to immediately set the interrupt flag on the thread so others can test for it:

  try {
      Thread.sleep(NOTE_DURATION);
  } catch (InterruptedException e) {
      // re-establish the interrupt condition
      Thread.currentThread.interrupt();
      ...
  }

这篇关于线程不中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆