【问题标题】:How to properly interrupt a thread in android如何正确中断android中的线程
【发布时间】:2014-07-09 12:44:55
【问题描述】:

在我的应用程序中,我有一个按钮,当它被点击时,我会启动一个新线程并更改按钮的文本。如果我再次按下按钮,它将开始更快地更改其文本。

我想在第二次按下按钮时中断线程。正确的做法是什么?

public class TestActivity extends Activity {

 Button btn;
 int i = 0;

 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
     btn = (Button)findViewById(R.id.btn);
     btn.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           runThread();
       }
     });
 }

private void runThread() {
    new Thread() {
      public void run() {
          while (i++ < 1000) {
              try {
                  runOnUiThread(new Runnable() {

                      @Override
                      public void run() {
                          btn.setText("#" + i);
                      }
                  });
                  Thread.sleep(300);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
    }.start();
}

【问题讨论】:

    标签: java android multithreading


    【解决方案1】:

    在这种情况下,只需保留对线程的引用并使用 Thread.interrupt():

    private Thread runThread() {
    
    return new Thread() {
      public void run() {
          while (i++ < 1000) {
              try {
                  runOnUiThread(new Runnable() {
    
                      @Override
                      public void run() {
                          btn.setText("#" + i);
                      }
                  });
                  Thread.sleep(300);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
    }
    

    然后:

     btn.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           if (myThread != null) myThread.interrupt();
           myThread = runThread();
           myThread.start();
       }
     });
    

    阅读这篇文章了解更多信息和选项:

    How to properly stop the Thread in Java?

    【讨论】:

    • 据我所知keepRunning没有任何影响,对吧?
    • 从另一个答案复制/粘贴错误 - 抱歉,已修复
    【解决方案2】:

    在我看来,最好的方法是使用变量来控制它。

    类似:

    while(i++ < 1000 && keepRunning)
    

    我认为这是一个很好的解决方案,因为它不会导致意外行为,因为您可以确定线程退出的确切时刻。

    额外的--

    作为建议,我还建议您将线程设置为非 Damon (setDaemon(false)),因为它会更改布局

    另外,给线程命名 (setName()) 以方便调试也是一个好习惯。

    【讨论】:

    • 或者他可以给 i 赋值 1000,
    • 这实际上是一个更优化的解决方案,但我建议创建一个 Max 变量,以防他某天更改它的值而忘记在所有地方进行更改。
    • 这是有道理的。你能澄清你的额外部分吗?我没听懂。
    • 是的,当然。我只是想知道将我的线程设置为非恶魔的目的是什么。
    • 如果它是非守护进程,那么你的线程将随着活动线程而死,否则它可能在活动终止后仍然调用runOnUiThread。
    【解决方案3】:

    现在您每次按下按钮时都会启动一个新线程。

    这样的事情应该可以工作。

    public class TestActivity extends Activity {
    
    Button btn;
    int i = 0;
    Thread countThread = null;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    countThread = new Thread() {
        public void run() {
          while (i++ < 1000) {
              try {
                  runOnUiThread(new Runnable() {
    
                      @Override
                      public void run() {
                          btn.setText("#" + i);
                      }
                  });
                  Thread.sleep(300);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
     }
     btn = (Button)findViewById(R.id.btn);
     btn.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           runThread();
       }
     });
    }
    
    private void runThread() {
      if(countThread != null) {
        if(countThread.isAlive()) {
            countThread.stop();
        } else {
            countThread.start();
        }
      }
    }
    

    我只有一个文本编辑器,所以我不能保证这是否能解决您的问题。

    【讨论】:

      【解决方案4】:

      您可以使用thread.interrupt()interrupt 线程。

      【讨论】:

        【解决方案5】:

        试试这个,只要取另一个变量 j,它就会处理你的代码:-

        public class TestActivity extends Activity {
        
             Button btn;
             int i = 0,j=0;
        
             @Override
             public void onCreate(Bundle savedInstanceState) {
                 super.onCreate(savedInstanceState);
                 setContentView(R.layout.main);
                 btn = (Button)findViewById(R.id.btn);
                 btn.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View v) {
                        j=1;
                       runThread();
                   }
                 });
             }
        
            private void runThread() {
                new Thread() {
                  public void run() {
                      while (i++ < 1000) {
                          try {
                              runOnUiThread(new Runnable() {
        
                                  @Override
                                  public void run() {
                                      if(j==1){
                                      btn.setText("#" + i);
                                       j=0;
                                       }
                                        else
                                            Thread.interrupted();
                                  }
                              });
                              Thread.sleep(300);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  }
                }.start();
            }
        

        【讨论】:

        • @user3764893,好的,只需使用 Thread.interrupted();在其他部分,我已经编辑了我的答案,请检查一下......
        【解决方案6】:

        您可以在 Android 中使用普通的 Thread(并为您的用例调用 interrupt()),但框架通过围绕线程提供帮助类来提供其他更好的选择。其他选项可以参考官方documentation页面。

        HandlerThread 是首选。如果您选择HandlerThread,您可以致电quitSafely()quit() 获取您的用例。

        相关帖子:

        Why use HandlerThread in Android

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-23
          • 1970-01-01
          • 2015-06-28
          • 2014-09-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-27
          • 1970-01-01
          相关资源
          最近更新 更多