2011-12-14 25 views
59

Tôi muốn biết đó là cách tốt nhất để ngăn chặn chuỗi trong Android. Tôi biết tôi có thể sử dụng AsyncTask thay vì nó và có phương pháp cancel(). Tôi phải sử dụng Threads trong tình huống của mình. Đây là cách tôi đang sử dụng chuỗi:cách tốt nhất và an toàn trên Android để ngăn chặn chủ đề

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

Vì vậy, bất kỳ ai có ý tưởng nào là cách tốt nhất để ngăn chặn chuỗi?

Trả lời

13

Phương pháp Thread.stop() có thể được sử dụng để chặn một chuỗi đã không còn được dùng nữa; để biết thêm thông tin xem; Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

Đặt cược tốt nhất của bạn là có một biến mà chính chuỗi đó tự hỏi, và tự nguyện thoát nếu biến bằng một giá trị nhất định. Sau đó, bạn thao tác biến bên trong mã của mình khi bạn muốn chuỗi thoát. Thay vào đó, bạn có thể sử dụng một số AsyncTask để thay thế.

+4

AsyncTask không thực sự là một thay thế cho cơ chế gián đoạn, nó còn là công cụ tương tác với giao diện người dùng. Như tôi đã chỉ ra trong câu trả lời của tôi, bạn sẽ vẫn phải triển khai cùng một cơ chế trong AsyncTask như trong bất kỳ luồng chung nào, nếu bạn muốn có thể dừng nó trong khi thực thi. – Malcolm

58

Bạn nên thực hiện ngắt hỗ trợ luồng. Về cơ bản, bạn có thể gọi số yourThread.interrupt() để dừng luồng và, trong phương thức run() của bạn, bạn cần phải định kỳ kiểm tra trạng thái của Thread.interrupted()

Có hướng dẫn tốt here.

+0

Cảm ơn, tôi đã tìm kiếm hủy() hoặc dừng() mọi lúc. –

+0

trông sạch sẽ và hoạt động đáng tin cậy. câu trả lời tốt, cảm ơn bạn. –

24

Tình huống này không theo bất kỳ cách nào khác với Java chuẩn. Bạn có thể sử dụng cách tiêu chuẩn để dừng chuỗi:

class WorkerThread extends Thread { 
    volatile boolean running = true; 

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

Ý tưởng chính là kiểm tra giá trị của trường theo thời gian. Khi bạn cần dừng chuỗi, bạn đặt running thành sai. Ngoài ra, như Chris đã chỉ ra, bạn có thể sử dụng cơ chế gián đoạn.

Nhân tiện, khi bạn sử dụng AsyncTask, apporach của bạn sẽ không khác nhiều. Điểm khác biệt duy nhất là bạn sẽ phải gọi phương thức isCancel() từ nhiệm vụ của mình thay vì có một trường đặc biệt. Nếu bạn gọi cancel(true), nhưng không triển khai cơ chế này, luồng vẫn không tự dừng, nó sẽ chạy đến cuối.

2

Hiện nay và tiếc là chúng tôi không thể làm bất cứ điều gì để ngăn chặn các chủ đề ....

Thêm mục nào đó để câu trả lời của Matt chúng ta có thể gọi interrupt() nhưng điều đó không ngăn chặn chủ đề ... Chỉ cần nói với hệ thống để ngăn chặn các chủ đề khi hệ thống muốn giết một số chủ đề. Phần còn lại được thực hiện bởi hệ thống và chúng tôi có thể kiểm tra bằng cách gọi interrupted().

[p.s. : Nếu bạn đang thực sự đi với interrupt() Tôi sẽ yêu cầu bạn thực hiện một số thí nghiệm với một giấc ngủ ngắn sau khi gọi interrupt()]

-1

Bên trong bất kỳ lớp Hoạt động nào bạn tạo một phương thức sẽ gán NULL cho cá thể chuỗi có thể được sử dụng như một thay thế cho phương thức stop() đã ngừng sử dụng để ngừng thực thi luồng:

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; 
    } 
} 
} 

Điều này làm việc cho tôi mà không gặp vấn đề gì.

+2

Cảm ơn bạn rất nhiều! Tôi đã tìm kiếm một giải pháp như thế này trong khoảng một năm nay và đây là giải pháp duy nhất hoạt động! – Pkmmte

+10

Đặt biến 'Thread' thành' null' sẽ không làm gì để dừng chuỗi. Đặt đối số thành 'null' bên trong' stopThread' là một sự lãng phí thời gian hoàn toàn. –

+1

Làm thế nào điều này có thể ngăn chặn các chủ đề? Tại sao có phiếu bầu tích cực về điều này? – mvd

16

Trên Android, các quy tắc tương tự áp dụng như trong môi trường Java bình thường. Trong các chủ đề Java không bị giết, nhưng việc dừng một sợi chỉ được thực hiện theo cách hợp tác . Chủ đề được yêu cầu chấm dứt và sau đó luồng có thể tắt một cách duyên dáng.

Thường thì trường volatile boolean được sử dụng mà chuỗi định kỳ kiểm tra và chấm dứt khi được đặt thành giá trị tương ứng.

tôi sẽ không sử dụng một boolean để kiểm tra xem thread nên chấm dứt. Nếu bạn sử dụng volatile làm công cụ sửa đổi trường, điều này sẽ hoạt động đáng tin cậy, nhưng nếu mã của bạn trở nên phức tạp hơn, thay vào đó sử dụng các phương pháp chặn khác trong vòng while, có thể xảy ra, mã của bạn sẽ không chấm dứt ở tất cả hoặc ít nhất mất nhiều thời gian hơn như bạn có thể muốn.

Một số phương pháp thư viện chặn nhất định hỗ trợ gián đoạn.

Mọi chủ đề đã có cờ boolean trạng thái bị gián đoạn và bạn nên tận dụng nó. Nó có thể được thực hiện như thế này:

public void run() { 

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

} 

public void cancel() { interrupt(); } 

Mã nguồn lấy từ Java Concurrency in Practice. Vì phương thức cancel() là công khai, bạn có thể cho phép một luồng khác gọi phương thức này như bạn muốn.

Ngoài ra còn có phương thức tĩnh được đặt tên kém interrupted để xóa trạng thái bị gián đoạn của chuỗi hiện tại.

+1

Trong Android Studio, java.lang ngoại lệ. InterruptedException 'không bao giờ được ném vào khối thử tương ứng? – CraPo

+0

@CraPo Thêm vòng lặp này trước khi while: 'if (Thread.interrupted()) {throw new InterruptedException();}' – Kosso

1

Vấn đề là bạn cần kiểm tra chủ đề là đang chạy hay không?! Dòng:

private boolean runningThread = false; 

Trong thread:

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(); 

Nếu bạn muốn dừng thread bạn nên thực hiện các lĩnh vực dưới đây

private boolean runningThread = false; 
1

Có 2 cách sau đây ưa thích để ngăn chặn một chủ đề.

  1. Tạo biến boolean dễ bay hơi và thay đổi giá trị thành sai và kiểm tra bên trong chuỗi.

    dễ bay hơi isRunning = false;

    public void run() { if (! IsRunning) {return;}}

  2. Hoặc bạn có thể sử dụng phương pháp ngắt() có thể được nhận trong một chủ đề.

    SomeThread.interrupt();

    public void run() { if (Thread.currentThread.isInterrupted()) {return;}}

0

tôi đã sử dụng phương pháp này.

Looper.myLooper().quit(); 

bạn có thể thử.

0

Điều này làm việc cho tôi như thế này. Giới thiệu một biến tĩnh trong hoạt động chính và thường xuyên kiểm tra nó như thế nào tôi đã làm là dưới đây.

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; 



     } 
    } 

} 
Các vấn đề liên quan