2011-09-10 6 views
5

मैं थ्रेड, हैंडलर, लूपर्स इत्यादि के बारे में बहुत कुछ पढ़ रहा हूं और मैं बहुत उलझन में हूं। मेरे ऐप में मैं पहली गतिविधि पृष्ठभूमि कार्यकर्ता शुरू करना चाहता हूं। यह पृष्ठभूमि कार्यकर्ता लगातार टीसीपी सॉकेट से डेटा का अनुरोध करेगा और (आशा है कि) डेटा आने पर यूआई थ्रेड में नई जानकारी पोस्ट करेगा। यदि उपयोगकर्ता किसी नई गतिविधि में संक्रमण करता है तो पृष्ठभूमि को इसकी बात करने की आवश्यकता होती है लेकिन केवल यूआई थ्रेड को अलग-अलग संदेश भेजते हैं ताकि यह तदनुसार नया लेआउट अपडेट कर सके।एंड्रॉइड: बैकग्राउंड थ्रेड से यूआई थ्रेड तक संदेश पास करने का उचित तरीका?

यहाँ मैं अब तक किया है ... यह मेरा मुख्य गतिविधि फ़ाइल

public class MyTCPTest extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // set the layout 
     setContentView(R.layout.main); 
     // create a handler to handle messages from bg thread 
     Handler handler = new Handler(); 

     BgWorkerThread bgw = new BgWorkerThread(); 
     bgw.start(); 
} 

अन्य फ़ाइल मैं इस तरह मेरी पृष्ठभूमि कार्यकर्ता धागा परिभाषित में में है ...

public class BgWorkerThread extends Thread {  
@Override 
public void run(){ 

    while(true) 
    { 
     try { 
     // simulate a delay (send request for data, receive and interpret response) 
     sleep(1000); 

        // How do I send data here to the UI thread? 

     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

हैं यूआई एक अलग गतिविधि के लिए स्विच करेगा यह धागा चल रहा है? साथ ही, यह धागा कैसे पता चलता है कि संदेश भेजने के लिए कौन सी गतिविधि है? जाहिर है, मैं चाहता हूं कि यह हमेशा उस गतिविधि को डेटा भेज दें जो वर्तमान में सक्रिय है। क्या यह स्वचालित रूप से होता है?

अंत में, जब यूआई एक अलग गतिविधि पर स्विच करता है तो bgworker को अधिसूचित करने की आवश्यकता होती है ताकि वह नए गतिविधि लेआउट से प्रासंगिक डेटा का अनुरोध करना शुरू कर सके। परिवर्तन के कार्यकर्ता को सूचित करने का सबसे अच्छा तरीका क्या है? क्या मैं बस BgWorkerThread क्लास में सार्वजनिक विधि नहीं बना सकता जिसे क्रियाएँ लोड होने पर बुलाया जा सकता है?

उत्तर

1

मुझे लगता है कि आप यूआई कॉलबैक तंत्र की तलाश में हैं। मैंने यहां एक समान प्रश्न का उत्तर दिया: Best way to perform an action periodically [while an app is running] - Handler?। जैसा कि आप देख सकते हैं, मैं Handler इंस्टेंस बनाकर और फिर sendEmptyMessage() पर कॉल करके पृष्ठभूमि थ्रेड से यूआई को एक संदेश भेज रहा हूं। अन्य प्रकार के संदेश आप भेज सकते हैं, लेकिन यह एक मामूली उदाहरण है।

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

+0

ट्रैविस लिंक के लिए धन्यवाद हालांकि मैं अभी भी उलझन में हूं। अंतर यह है कि आपका सभी कोड एक ही कक्षा में प्रतीत होता है। मेरा पृष्ठभूमि कार्यकर्ता यह अपनी कक्षा है जो थ्रेड को बढ़ाता है। यह गतिविधि वर्ग से एक अलग वर्ग है तो मैं उस वर्ग/गतिविधि के हैंडलर तक कैसे पहुंचूं? – PICyourBrain

3

मैंने एक ही कोड और निम्नलिखित SO Question में एक और विस्तृत कदम दिखाए हैं।

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

यहाँ से यूआई थ्रेड को सूचित करने में कोड करने के लिए आसान अपने BackgroundThread

public class ResponseHandler extends AsyncTask<Void, String, Integer> { 
    boolean isConnectionClosed = false; 
    Map<Integer, Handler> requestIdToMapHandler; 

    public ResponseHandler() { 
     this.requestIdToMapHandler = new HashMap<Integer, Handler>(); 
    } 

    @Override 
    protected Integer doInBackground(Void... params) { 
     int errorCode = 0; 

     try { 
      // while not connection is not close 
      while(!isConnectionClosed){ 
       // blocking call from the device/server 
       String responseData = getResponse(); 

       // once you get the data, you publish the progress 
       // this would be executed in the UI Thread 
       publishProgress(responseData); 
      } 
     } catch(Exception e) { 
      // error handling code that assigns appropriate error code 
     } 

     return errorCode; 

    } 

    @Override 
    protected void onPostExecute(Integer errorCode) { 
     // handle error on UI Thread 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     String responseData = values[0]; 

     // the response contains the requestId that we need to extract 
     int requestId = extractId(responseData); 

     // next use the requestId to get the appropriate handler 
     Handler uiHandler = getUIHandler(requestId); 

     // send the message with data, note that this is just the illustration 
     // your data not necessary be jut String 
     Message message = uiHandler.obtainMessage(); 
     message.obj = responseData; 
     uiHandler.sendMessage(message); 
    } 

    /*** 
    * Stub code for illustration only 
    * Get the handler from the Map of requestId map to a Handler that you register from the UI 
    * @param requestId Request id that is mapped to a particular handler 
    * @return 
    */ 
    private Handler getUIHandler(int requestId) { 
     return null; 
    } 

    /*** 
    * Stub code for illustration only, parse the response and get the request Id 
    * @param responseId 
    * @return 
    */ 
    private int extractId(String responseId) { 
     return 0; 
    } 

    /*** 
    * Stub code for illustration only 
    * Call the server to get the TCP data. This is a blocking socket call that wait 
    * for the server response 
    * @return 
    */ 
    private String getResponse() { 
     return null; 
    } 
} 
0

के लिए ठूंठ/स्यूडोकोड आप उपयोग कर सकते हैं

runOnUIThread(new Runnable { 

public void run() { 
//Update your UI here like update text view or imageview etc 

} 

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