2012-10-19 7 views
6

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

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

मैंने AsyncTask का उपयोग करके एंड्रॉइड में एक ही एप्लीकेशन विकसित किया और यह अच्छी तरह से काम कर रहा है। लेकिन ब्लैकबेरी में, क्योंकि ऐसी कोई कक्षा नहीं है, मैंने invokeLater() विकल्प का उपयोग किया। संचार सर्वर और बीबी डिवाइस के बीच ठीक काम करता है, लेकिन यूआई ब्लैकबेरी पर जमे हुए है।

किसी को भी यह अधिकार है कि यह अधिकार कैसे प्राप्त करें?

+2

मैं सिर्फ एक सादे पुराने जावा धागे का प्रयोग करेंगे क्रियान्वित किया जा सकता ... – Lawrence

+0

उपभोक्ता/निर्माता समस्या: http://en.wikipedia.org/wiki/Producer-consumer_problem –

+0

मुझे वास्तव में वास्तव में यह दृष्टिकोण पसंद है। एपीआई की नकल करने का प्रयास करके, मुझे लगता है कि मेरे कोड का अधिक एंड्रॉइड और ब्लैकबेरी के बीच पुन: प्रयोज्य हो सकता है। मैंने इसे कुछ सामान्य वर्गों के साथ किया है। – Nate

उत्तर

12

विशाल सही रास्ते पर है, लेकिन एक छोटे से अधिक Android के AsyncTask मिलान करने के लिए जरूरत है। चूंकि ब्लैकबेरी पर जावा 1.3 के साथ enums और जेनेरिक उपलब्ध नहीं हैं, इसलिए आप एंड्रॉइड एपीआई से बिल्कुल मेल नहीं खा सकते हैं।

लेकिन, आप कुछ इस तरह कर सकता है (परीक्षण नहीं किया ... यह आपके लिए सिर्फ एक शुरुआती बिंदु है):

import net.rim.device.api.ui.UiApplication; 

public abstract class AsyncTask { 

    public static final int FINISHED = 0; 
    public static final int PENDING = 1; 
    public static final int RUNNING = 2; 

    private int _status = PENDING; 
    private boolean _cancelled = false; 
    private Thread _worker; 

    /** subclasses MUST implement this method */ 
    public abstract Object doInBackground(Object[] params); 

    protected void onPreExecute() { 
     // default implementation does nothing 
    } 
    protected void onPostExecute(Object result) { 
     // default implementation does nothing 
    } 
    protected void onProgressUpdate(Object[] values) { 
     // default implementation does nothing 
    } 
    protected void onCancelled() { 
     // default implementation does nothing 
    } 
    protected void onCancelled(Object result) { 
     onCancelled(); 
    } 

    public final int getStatus() { 
     return _status; 
    } 

    public final boolean isCancelled() { 
     return _cancelled; 
    } 

    public final boolean cancel(boolean mayInterruptIfRunning) { 
     if (_status == FINISHED || _cancelled) { 
      return false; 
     } else { 
      _cancelled = true; 
      if (mayInterruptIfRunning && _status == RUNNING) { 
       // NOTE: calling Thread.interrupt() usually doesn't work 
       // well, unless you don't care what state the background 
       // processing is left in. I'm not 100% sure that this is how 
       // Android's AsyncTask implements cancel(true), but I 
       // normally just cancel background tasks by letting the 
       // doInBackground() method check isCancelled() at multiple 
       // points in its processing. 
       _worker.interrupt(); 
      } 
      return true; 
     } 
    } 

    protected final void publishProgress(final Object[] values) { 
     // call back onProgressUpdate on the UI thread 
     UiApplication.getUiApplication().invokeLater(new Runnable() { 
      public void run() { 
       onProgressUpdate(values); 
      } 
     }); 
    } 

    private void completeTask(final Object result) { 
     // transmit the result back to the UI thread 
     UiApplication.getUiApplication().invokeLater(new Runnable() { 
      public void run() { 
       if (isCancelled()) { 
        onCancelled(result); 
       } else { 
        onPostExecute(result); 
       } 
       // TODO: not sure if status should be FINISHED before or after onPostExecute() 
       _status = FINISHED; 
      } 
     }); 
    } 

    public AsyncTask execute(final Object[] params) throws IllegalStateException { 
     if (getStatus() != PENDING) { 
      throw new IllegalStateException("An AsyncTask can only be executed once!"); 
     } else { 
      try { 
       onPreExecute(); 

       _worker = new Thread(new Runnable() { 
        public void run() { 
         try { 
          // run background work on this worker thread 
          final Object result = doInBackground(params); 
          completeTask(result); 
         } catch (Exception e) { 
          // I believe if Thread.interrupt() is called, we'll arrive here 
          completeTask(null); 
         } 
        } 
       }); 
       _status = RUNNING; 
       _worker.start(); 
      } catch (Exception e) { 
       // TODO: handle this exception 
      } 
     } 

     return this; 
    } 

} 

इसके अलावा, यह मन Android के लिए थ्रेडिंग नियमों में रखना ज़रूरी है AsyncTask, जो उपरोक्त क्रियान्वयन के लिए लागू है, भी:

थ्रेडिंग नियम कुछ सूत्रण वाले नियम पालन किया जाना चाहिए च कर रहे हैं या इस वर्ग को ठीक से काम करने के लिए:

  • AsyncTask क्लास को UI थ्रेड पर लोड किया जाना चाहिए। यह JELLY_BEAN के रूप में स्वचालित रूप से किया जाता है।

  • कार्य उदाहरण UI थ्रेड पर बनाया जाना चाहिए।

  • निष्पादित (पैराम्स ...) यूआई थ्रेड पर लागू किया जाना चाहिए।

  • PreExecute(), onPostExecute (परिणाम), doInBackground (पैराम्स ...) पर, प्रोग्रेसअपडेट (प्रगति ...) पर मैन्युअल रूप से कॉल न करें।

  • कार्य केवल एक बार (यदि एक दूसरा निष्पादन का प्रयास किया है एक अपवाद फेंक दिया जाएगा।)

+0

आपको बहुत धन्यवाद। यह काम किया :) –

+1

@Nate +1 और मेरे लिए कुछ महान सीखने की चीज़ें। धन्यवाद नाट –

+0

@ विशाललस, कोई समस्या नहीं। आपको निश्चित रूप से सही विचार था। और, अब मैंने इस उत्तर के लिए कुछ लिखा है, मैं इसे ब्लैकबेरी ऐप्स में उपयोग करना शुरू कर दूंगा :) – Nate

4

आप कक्षा बना सकते हैं जो कक्षा AsyncTask के मेरे कार्यान्वयन को बढ़ाता है। शुभकामनाएँ :)

यहां विधियों onPreExecute, onPostExecute UI थ्रेड पर निष्पादित किए गए हैं और doInBackground को कार्यकर्ता धागे पर बुलाया जाता है। चूंकि onPreExecute, onPostExecute अमूर्त हैं आप उन्हें ओवरराइड कर सकते हैं और प्रगति संवाद को दिखाने और खारिज करने जैसे अपना कार्यान्वयन प्रदान कर सकते हैं।

अनुक्रम जिसमें तरीकों मिल मार डाला है 1) onPreExecute 2) doInBackground 3) onPostExecute

import net.rim.device.api.ui.UiApplication; 
import net.rim.device.api.ui.component.Dialog; 

public abstract class AsyncTask { 
    Runnable runnable; 
    Thread threadToRun; 

    public abstract void onPreExecute(); 

    public abstract void onPostExecute(); 

    public abstract void doInBackground(); 

    public void execute() { 
    try { 
     runnable = new Runnable() { 

      public void run() { 
       // TODO Auto-generated method stub 
       UiApplication.getUiApplication().invokeLater(
         new Runnable() { 

          public void run() { 
           // TODO Auto-generated method stub 
           onPreExecute(); 
          } 
         }); 

       doInBackground(); 

       UiApplication.getUiApplication().invokeLater(
         new Runnable() { 

          public void run() { 
           // TODO Auto-generated method stub 
           onPostExecute(); 
          } 
         }); 

      } 
     }; 

     threadToRun = new Thread(runnable); 
     threadToRun.start(); 
    } catch (Exception e) { 
     // TODO: handle exception 
     Dialog.alert("Async Error Occured. " + e.toString()); 
    } 
} 
} 
+0

उम्मीद है कि यह मदद करता है। –

+2

हालांकि यह एक अच्छी शुरुआत है, कुछ मुद्दे हैं। (1) 'onPreExecute()' उपरोक्त आपके कार्यान्वयन में 'doInBackground() 'से पहले चलाने की गारंटी नहीं है, और लगभग निश्चित रूप से ** doInBackground()' से पहले ** शुरू नहीं होगा। (2) एंड्रॉइड के 'AsyncTask' में पृष्ठभूमि प्रसंस्करण के दौरान' प्रकाशित प्रोग्रेस() 'के लिए एक विधि भी शामिल है। – Nate

+0

@Nate यह बहुत अच्छा होगा अगर आप कृपया यह समझाएं कि यह क्यों गारंटी नहीं है कि 'onPreExecute() ''InInBackground()' से पहले नहीं कहा जाएगा क्योंकि इससे मुझे इस कार्यान्वयन में सुधार करने में मदद मिलेगी। मैंने प्रगति संकेतक दिखाने और प्रक्रिया पूरी होने पर इसे खारिज करने के लिए अपनी कई ब्लैकबेरी परियोजनाओं में इस कार्यान्वयन का उपयोग किया है। –

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