2015-06-14 6 views
6

मैं जो करने का प्रयास कर रहा था वह हर बार जब काउंटर 5 का बहुमत बन जाता है तो टाइमर विलंब को कम करना था। लेकिन जैसे ही कोड ब्लॉक में प्रवेश करता था, तो उसने टाइमर को बढ़ाने में रोक लगा दी। मुझे समझ में नहीं आता कि क्या हो रहा है।रनटाइम के दौरान एंड्रॉइड में नींद/टाइमर थ्रेड की देरी को कैसे बदला जाए?

इस कोड

thread=new Thread(){ 
    public void run(){ 
     try{ 
      if(count%5==0) 
       timre--; 
      else{ 
       //do nothing 
      } 
      //*******PROGRESS UPDATE********// 
      for(t=0;t<=100;t++) { 
       sleep((timre)/100); 
       progress.setProgress(t); 
       t += 1; 
      } 
      //****PROGRESS UPDATE OVER****// 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     finally { 
      finish(); 
     } 
    }//run ends 
};//thread ends 
thread.start();//timer starts 
+0

क्या आप अधिक कोड दिखा सकते हैं? आप टाइमर शुरू करते हैं? – Wishmaster

उत्तर

5

Thread.sleep() की गारंटी नहीं है। इसका मतलब यह है कि इस अवधि के लिए विषय के बाहर होने वाले विभिन्न कारणों से आप उस अवधि के लिए सो सकते हैं या नहीं सो सकते हैं।

आप तो आप शायद पर लैंड करेगा "एंड्रॉयड में टाइमर" के लिए शुद्ध खोज करते हैं इन दो: https://developer.android.com/reference/java/util/Timer.html और https://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor.html

आप उन्हें बाहर की जाँच, हालांकि, मैं उन का उपयोग नहीं होगा सकता है के रूप में वे अन्य का एक बहुत प्रदान करते हैं नाम के रूप में कार्यशीलता का सुझाव है ("अनुसूचित थ्रेडपूलएक्सएटर")। आपको इसकी आवश्यकता नहीं है क्योंकि बहुत सारे धागे आदि के साथ बड़ी प्रणालियों के लिए इसका उपयोग होने की संभावना है ...

यदि मैं सही ढंग से आपका कोड समझता हूं तो आप प्रगति पट्टी को अपडेट करने का प्रयास कर रहे हैं। जो आप करने की कोशिश कर रहे हैं उसके लिए मैं एक हैंडलर का उपयोग करने का सुझाव दूंगा।हैंडलर का मुख्य उपयोगों में से एक संदेशों शेड्यूल करने के लिए है और डॉक्स यहाँ के रूप में विनिर्दिष्ट भविष्य में किसी समय के रूप में क्रियान्वित किया जाना runnables: http://developer.android.com/reference/android/os/Handler.html

मैं इस तरह यह करना होगा:

int counter = 0; 
int delayInMs = 5000; // 5 seconds 
Handler timer = new Handler(new Handler.Callback() { 

@Override 
public boolean handleMessage(Message msg) { 
    counter++; 
    // If the counter is mod 5 (or whatever) lower the delay 
    if (counter % 5 == 0) { 
    delayInMs/=100; // Or any other calculation. 
    } 
    // If the counter reaches 100 the counting will not continue. 
    if (counter <= 100) { 
    // If the counter has not reached the condition to stop, the handler 
    // will call the timer again with the modified (or not) delay. 
    timer.sendEmptyMessageDelayed(0, delayInMs); 

    // Change progress 
    updateProgress(counter); 
    } 
    return true; 
} 
}); 
// ... 

// Somwhere in the code to start the counter 
timer.sendEmptyMessageDelayed(0, delayInMs); // starts the timer with the initial 5 sec delay. 

एक और चीज़। उस लाइन में जहां आपके पास यह कोड है:

progress.setProgress(t); 

अन्य धागे से यूआई तत्वों को कॉल करते समय सावधान रहें, यह सिरदर्द का स्रोत है। यदि आपका हैंडलर किसी अन्य थ्रेड में है तो आपको उस कॉल को फ़ंक्शन में लपेटना चाहिए और सुनिश्चित करें कि इसे मुख्य थ्रेड (यानी यूआई थ्रेड) से बुलाया जाता है। इसे प्राप्त करने के कई तरीके (हमेशा आवश्यक नहीं)। उनमें से एक इस तरह है:

private void updateProgress(int counter) { 
    WhateverActivity.this.runOnUiThread(new Runnable() { 
    public void run() { 
     progress.setProgress(counter); 
    } 
    }); 
} 
6

धागे (और sleep()) एंड्रॉयड में मुश्किल हो रहा है। एक CountDownTimer बजाय

CountDownTimer counter; 
startTimer(); 
counter.start(); 

private void startTimer() { 

    counter = new CountDownTimer(4000, 500){ 

     @Override 
     public void onFinish() { 

      **DO YOUR STUFF HERE** 
     } 
     @Override 
     public void onTick(long millisUntilFinished) { 
     } 
    }; 
} 

कॉल समारोह startTimer() का उपयोग कर भी आप चाहते हैं की कोशिश करो और एक ही समय में counter शुरू करते हैं।

2

क्या आप कृपया बता सकते हैं कि timre और count यह कब शुरू होता है? मुझे लगता है कि वे जिस स्थिति में 0 कर रहे हैं,

if(count%5==0) //Immediately true. 0 mod 5 == 0. 
    timre--; // 0-- = -1? 
else{ 
    //do nothing 
} 

इसका मतलब यह होगा कि आपके for loop-0.01 मिलीसेकंड के लिए सो रहा है?

for(t=0;t<=100;t++) { 
    sleep((timre)/100); 
    progress.setProgress(t); 
    t += 1; 
} 

यह स्पष्टीकरण दें कि इसे तुरंत setProgress विधि चल रहा है होगा। लेकिन हे, मैं गलत हो सकता था। हमें बताएं कि कोड को हिट करते समय वे चर किस प्रकार शुरू किए गए हैं या वर्तमान में सेट किए गए हैं!

धन्यवाद,

2

मुझे लगता है कि आप पाश के लिए अंदर अगर ब्लॉक शामिल होना चाहिए। जैसा कि आपने कोड लिखा है, अगर थ्रेड केवल तभी शुरू होता है जब थ्रेड शुरू होता है, तो इसे केवल एक बार निष्पादित किया जाता है। इसलिए, लूप के अंदर टाइमर चर कभी नहीं बदला जाता है।

मैं क्या लगता है कि अपने कोड की तरह है दिखना चाहिए:

thread=new Thread(){ 
public void run(){ 
    try{ 

     //*******PROGRESS UPDATE********// 
     for(t=0;t<=100;t++) { 
      if(count%5==0) 
       timre--; 
      sleep((timre)/100); 
      progress.setProgress(t); 
      t += 1; 
     } 
     //****PROGRESS UPDATE OVER****// 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    finally { 
     finish(); 
    } 
}//run ends 
};//thread ends 
thread.start();//timer starts 
2

कुछ इस तरह काम करना चाहिए:

thread=new Thread(){ 

++ private float timre; 

++ public void setTimre(float timre) { 
++ this.timre = timre; 
++ } 

public void run(){ 
    try{ 
     if(count%5==0) 
      timre--; 
     else{ 
      //do nothing 
     } 
     //*******PROGRESS UPDATE********// 
     for(t=0;t<=100;t++) { 
      sleep((timre)/100); 
      progress.setProgress(t); 
      t += 1; 
     } 
     //****PROGRESS UPDATE OVER****// 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    finally { 
     finish(); 
    } 
}//run ends 
};//thread ends 

thread.start(); 

++ if(condition to change the sleeping time) { 
++ try { 
++  thread.interrupt(); 
++  catch(Exception e) { 
++   e.doSomethingCoolWithit(); 
++ } 

++ thread.setTimre(newTimre); 
++ thread.start(); 
++ } 
} 

हालांकि यह शायद असफल हो जायेगी जब thread.start कॉल करने के लिए() की कोशिश कर रहा, दूसरी बार, और आपको एक नया धागा बनाने की आवश्यकता हो सकती है।

+0

जैसा कि मैंने कहा था, आपको अपने वर्तमान धागे को रोकने और इसे फिर से चालू करने की आवश्यकता हो सकती है –

2

रूप @Amaresh का सुझाव दिया, आप कार्य करने के लिए CountDownTimer उपयोग करना चाहिए। आपका क्रियान्वयन दो तरीके

  • इसकी कोई गारंटी नहीं है कि एक धागा हमेशा चला सकते हैं और धागा भीतर समय तथाकथित असली घड़ी समय के रूप में ही नहीं हो सकता है में त्रुटिपूर्ण है। आप here से नींद और समय के बारे में अधिक जानकारी प्राप्त कर सकते हैं।

  • मुझे लगता है कि प्रगति में परिवर्तन होने पर आप यूआई को अपडेट करने जा रहे हैं। इस मामले में, CountDownTimer आपको अतिरिक्त हैंडलर के बिना मुख्य थ्रेड पर कॉलबैक बनाने के तरीके पर परेशानी बचाता है।

आप रुचि रखते हैं, आप Android स्रोत कोड से CountDownTimer के कार्यान्वयन की जांच कर सकते हैं, यह सीधे आगे और समझने में आसान है।

यदि आपका कोड समय लेने वाली सेवा पर चल रहा है, तो सुनिश्चित करें कि आपका टाइमर वास्तव में काम करता है जब डिवाइस निष्क्रिय हो जाता है। इस मामले में, आपको WakefulBroadcastReceiver के साथ जोड़ा गया जागरूक अलार्म लागू करने की आवश्यकता हो सकती है।

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