2011-12-14 113 views
59

我想知道哪些是阻止Android中线程的最佳方式。我知道我可以使用AsyncTask代替它,并且有cancel()方法。我必须在我的情况下使用线程。下面是我如何使用线程:android最好和最安全的方式来停止线程

Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      //doing some work 
     } 
    }; 
new Thread(runnable).start(); 

因此,任何人有任何想法,这是停止线程的最佳方式?

回答

13

Thread.stop()方法,其可用于停止一个线程已被弃用;更多信息请参阅; Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

你最好的选择是有其线程本身协商的变量,并自愿当变量等于某个值退出。然后,当您希望线程退出时,您可以在代码中操作变量。或者,当然,您也可以使用AsyncTask

+4

AsyncTask并不是中断机制的替代品,它更像是一种与UI交互的工具。正如我在回答中指出的那样,如果您希望在执行期间能够停止它,您仍然必须在AsyncTask中实现与任何公共线程相同的机制。 – Malcolm 2011-12-14 14:45:15

58

你应该让你的线程支持中断。基本上,您可以拨打yourThread.interrupt()来停止线程,并且在您的run()方法中,您需要定期检查Thread.interrupted()的状态

有一个很好的教程here

+0

谢谢,我一直在寻找cancel()或stop()。 – 2016-02-17 09:38:43

+0

看起来干净,工作可靠。很好的答案,谢谢。 – 2017-06-15 20:19:51

24

这种情况不是从标准的Java不同的任何方式。您可以使用标准方式来停止线程:

class WorkerThread extends Thread { 
    volatile boolean running = true; 

    public void run() { 
     // Do work... 
     if (!running) return; 
     //Continue doing the work 
    } 
} 

主要想法是不时检查字段的值。当您需要停止线程时,将running设置为false。另外,正如克里斯指出的那样,你可以使用中断机制。

顺便说一句,当您使用的AsyncTask,您apporach不会相差太多。唯一的区别是您必须从您的任务中调用isCancel()方法,而不是使用特殊字段。如果你打电话给cancel(true),但是不执行这个机制,线程仍然不会自行停止,它会运行到最后。

2

目前,不幸的是,我们不能做任何事情来阻止线程....

添加东西,马特的答案,我们可以称之为interrupt(),但是这并不能阻止线程...只是告诉系统停止系统想要杀死一些线程时的线程。休息是由系统完成的,我们可以通过致电interrupted()进行检查。

[p.s. :如果你真的与interrupt()去我要问你叫interrupt()]

-1

里面你创建将分配NULL线程实例,它可以作为一种方法的任何活动类后,做一些实验,用很短的睡眠替代停止线程执行折旧stop()方法:

public class MyActivity extends Activity { 

private Thread mThread; 

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


     mThread = new Thread(){ 
     @Override 
     public void run(){ 
      // Perform thread commands... 
    for (int i=0; i < 5000; i++) 
    { 
     // do something... 
    } 

    // Call the stopThread() method. 
      stopThread(this); 
      } 
     }; 

    // Start the thread. 
     mThread.start(); 
} 

private synchronized void stopThread(Thread theThread) 
{ 
    if (theThread != null) 
    { 
     theThread = null; 
    } 
} 
} 

这个工作对我来说没有问题。

+2

非常感谢!大约一年来,我一直在寻找这样的解决方案,而且这是唯一的解决方案! – Pkmmte 2013-04-17 08:17:15

16

在Android上应用相同的规则作为一个正常的Java环境。 Java线程不会被终止,但是线程的停止是以合作方式完成的。线程被要求终止,然后线程可以优雅地关闭。

通常一个volatile boolean字段用于该线程周期性地检查,并且当它被设置为相应的值终止。

不会使用boolean检查线是否应终止。如果您使用volatile作为现场修改,这将工作可靠,但如果你的代码变得更加复杂,对于而是使用while环内的其他阻止方法,它可能发生,你的代码将不是在所有或至少终止你可能需要更长的需要更长的时间

某些阻断库方法支持中断。

每个线程都有已经是布尔标志中断状态,你应该利用它。它可以这样实现:

public void run() { 

    try { 
     while(!Thread.currentThread().isInterrupted()) { 
     // ... 
     } 
    } catch (InterruptedException consumed) 
     /* Allow thread to exit */ 
    } 

} 

public void cancel() { interrupt(); } 

源代码取自Java Concurrency in Practice。由于cancel()方法是公开的,因此您可以让另一个线程根据需要调用此方法。

还有一个名为不佳静态方法interrupted它清除当前线程的中断状态。

1

的事情是,你需要检查线程运行或不?! 现场:

private boolean runningThread = false; 

在线程:

new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (true) { 
        try { 
         Thread.sleep((long) Math.floor(speed)); 
         if (!runningThread) { 
          return; 
         } 
         yourWork(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }).start(); 

如果你想停止线程,你应该做以下领域

private boolean runningThread = false; 
1

有2种以下方式首选停止线。

  1. 创建一个易失性布尔变量并将其值更改为false并检查线程内部。

    volatile isRunning = false;

    公共无效的run(){ 如果(!isRunning){回报;}}

  2. 或者您可以使用它可以线程内部接收中断()方法。

    SomeThread.interrupt();

    公共无效的run(){ 如果(Thread.currentThread.isInterrupted()){返回;}}

0

我使用该方法。

Looper.myLooper().quit(); 

你可以试试。

0

这对我这样工作。在主要活动中引入一个静态变量,并定期检查它是如何做到的。

public class MainActivity extends AppCompatActivity { 


//This is the static variable introduced in main activity 
public static boolean stopThread =false; 



    protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    Thread thread = new Thread(new Thread1()); 
    thread.start(); 

    Button stp_thread= findViewById(R.id.button_stop); 

    stp_thread.setOnClickListener(new Button.OnClickListener(){ 
      @Override 
      public void onClick(View v){ 
       stopThread = true; 
      } 

    } 

    } 


    class Thread1 implements Runnable{ 

     public void run() { 

     // YOU CAN DO IT ON BELOW WAY 
     while(!MainActivity.stopThread) { 
      Do Something here 
     } 


     //OR YOU CAN CALL RETURN AFTER EVERY LINE LIKE BELOW 

     process 1 goes here; 

     //Below method also could be used 
     if(stopThread==true){ 
      return ; 
     } 
     // use this after every line 



     process 2 goes here; 


     //Below method also could be used 
     if(stopThread==true){ 
      return ; 
     } 
     // use this after every line 


     process 3 goes here; 


     //Below method also could be used 
     if(stopThread==true){ 
      return ; 
     } 
     // use this after every line 


     process 4 goes here; 



     } 
    } 

}