2011-12-14 4 views
59

मैं जानना चाहता हूं कि एंड्रॉइड में थ्रेड को रोकने का सबसे अच्छा तरीका कौन सा है। मुझे पता है कि मैं इसके बजाय AsyncTask का उपयोग कर सकता हूं और cancel() विधि है। मुझे अपनी स्थिति में थ्रेड का उपयोग करना है।थ्रेड को रोकने के लिए एंड्रॉइड सबसे अच्छा और सुरक्षित तरीका

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 वास्तव में बाधा तंत्र के लिए एक विकल्प नहीं है, यह यूआई के साथ बातचीत करने के लिए एक और साधन है। जैसा कि मैंने अपने उत्तर में बताया है, अगर आपको निष्पादन के दौरान इसे रोकने में सक्षम होना चाहते हैं, तो आपको अभी भी AsyncTask में एक ही सामान्य थ्रेड में उसी तंत्र को लागू करना होगा। – Malcolm

58

आपको अपना थ्रेड समर्थन इंटरप्ट बनाना चाहिए। असल में, आप थ्रेड को रोकने के लिए yourThread.interrupt() पर कॉल कर सकते हैं और, आपके रन() विधि में आपको समय-समय पर Thread.interrupted()

पर एक अच्छा ट्यूटोरियल here है।

+0

धन्यवाद, मैं हर समय रद्द() या रोक() को ढूंढ रहा था। –

+0

साफ दिखता है और विश्वसनीय काम करता है। अच्छा जवाब, धन्यवाद। –

24

यह स्थिति मानक जावा से किसी भी तरह से अलग नहीं है। आप एक धागा बंद करने के लिए मानक तरीके से उपयोग कर सकते हैं:

class WorkerThread extends Thread { 
    volatile boolean running = true; 

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

मुख्य विचार समय-समय पर फ़ील्ड का मान की जाँच करने के लिए है। जब आपको अपना धागा रोकने की आवश्यकता होती है, तो आप running को झूठी पर सेट करते हैं। इसके अलावा, जैसा कि क्रिस ने इंगित किया है, आप बाधा तंत्र का उपयोग कर सकते हैं।

वैसे, जब आप AsyncTask का उपयोग करते हैं, तो आपका ऐप्लिकेशन अधिक भिन्न नहीं होगा। केवल अंतर यह है कि आपको विशेष क्षेत्र रखने के बजाय अपने कार्य से isCancel() विधि को कॉल करना होगा। यदि आप cancel(true) पर कॉल करते हैं, लेकिन इस तंत्र को लागू न करें, तो थ्रेड अभी भी बंद नहीं होगा, यह अंत तक चलेगा।

2

वर्तमान और दुर्भाग्य से हम कुछ नहीं कर सकते धागा बंद करने के लिए ....

हम interrupt() कॉल कर सकते हैं लेकिन यह है कि धागा बंद नहीं मैट के जवाब के लिए कुछ जोड़ रहा है ... बस को रोकने के लिए प्रणाली को बताता है थ्रेड जब सिस्टम कुछ धागे को मारना चाहता है। बाकी प्रणाली द्वारा किया जाता है, और हम interrupted() पर कॉल करके इसे देख सकते हैं।

[पी। : क्या तुम सच में interrupt() के साथ जा रहे हैं, तो मैं आप से पूछना interrupt()]

-1

कॉल करने वाले किसी गतिविधि वर्ग आप एक विधि है कि शून्य उदाहरण है, जिसमें एक के रूप में इस्तेमाल किया जा सकता सूत्र में बाँधना आवंटित करेगा बनाने के अंदर के बाद एक छोटी नींद के साथ कुछ प्रयोग करने के लिए होगा धागा निष्पादन रोक के लिए विधि घिस स्टॉप() के लिए वैकल्पिक:

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

+10

'थ्रेड' वैरिएबल को' null' पर सेट करना थ्रेड को रोकने के लिए कुछ भी नहीं करेगा। 'स्टॉप थ्रेड' के अंदर तर्क को 'शून्य' पर सेट करना समय की पूरी बर्बादी है। –

+1

यह संभवतः थ्रेड को कैसे रोक सकता है? इस पर सकारात्मक वोट क्यों हैं? – mvd

16

एंड्रॉइड पर एक ही नियम सामान्य जावा वातावरण में लागू होते हैं। जावा धागे में नहीं मारा जाता है, लेकिन धागे को रोकना सहकारी तरीके में किया जाता है। थ्रेड को समाप्त करने के लिए कहा जाता है और थ्रेड फिर से बंद कर सकते हैं।

अक्सर 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

एंड्रॉइड स्टूडियो में यह कहता है, अपवाद 'java.lang। InterruptedException 'को संबंधित प्रयास ब्लॉक में कभी नहीं फेंक दिया जाता है? – CraPo

+0

@CraPo इसे लूप से पहले जोड़ें: 'if (Thread.interrupted()) {नया इंटरप्टेड एक्सेप्शन();}' – Kosso

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. एक अस्थिर बूलियन चर बनाएँ और गलत पर अपने मूल्य बदल सकते हैं और धागा अंदर की जाँच करें।

    अस्थिर isRunning = झूठा;

    सार्वजनिक शून्य रन() { if (! IsRunning) {वापसी;} }

  2. या आप व्यवधान() विधि जो एक धागा अंदर प्राप्त किया जा सकता है का उपयोग कर सकते हैं।

    कुछThread.interrupt();

    सार्वजनिक शून्य रन() { अगर (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; 



     } 
    } 

} 
संबंधित मुद्दे

 संबंधित मुद्दे