2012-01-26 19 views
17

संभव डुप्लिकेट कहा जाता है:
AsyncTask block UI threat and show progressbar with delayProgressDialog नहीं दिखाया जाता है जब AsyncTask.get()

मैं एक progressDialog दिखाने के लिए किसी भी सर्वर से JSON पुनः प्राप्त करते समय चाहते हैं। तो मैंने एक समाधान के रूप में AsyncTask का उपयोग किया था (सुनिश्चित नहीं है कि कोई अलग तरीका है)।

सबकुछ ठीक है, प्रोग्रेसडिअलॉग ठीक से काम करता है जब तक मैं AsyncTask उदाहरण का उपयोग कर .get() विधि को कॉल नहीं करता। मुझे लगता है कि यह किसी भी तरह यूआई अवरुद्ध कर रहा है। यहाँ मेरी AsyncTask है: यहाँ

public class myAsync extends AsyncTask<String, String, List> { 

    String message; // for dialog message 
    ProgressDialog progress; 
    Intent myIntent; 
    Context ctx; 

    public myAsync(String message, Context ctx) { 
     this.message = message; 
     this.ctx = ctx; 
     progress = new ProgressDialog(ctx); 
    } 

    @Override 
    protected void onPreExecute() { 
     progress.setMessage(message); 
     progress.setIndeterminate(true); 
     progress.setCancelable(false); 
     progress.show();  
    } 

    @Override 
    protected List doInBackground(String... params) { 
     //returns any list after the task 
     return anyList; 
    } 

    @Override 
    protected void onPostExecute(List result) { 
     if(progress.isShowing()) 
      progress.dismiss(); 
    } 
} 

और myActivity है जो कहता है AsyncTask:

myAsync asyncTask = new myAsync("Loading...", this); 
asyncTask.execute("Any string", "Other string"); 
asyncTask.get(); // If I comment out this line, ProgressDialog works 

के बाद, निष्पादित जब मैं doInBackground और onPostExecute से परिणाम दोनों वहाँ कोई समस्या नहीं है लॉग इन करने की कोशिश की। लेकिन अगर मैं .get() के साथ प्राप्त करना चाहता हूं तो परिणाम प्रोग्रेसडिअलॉग दिखाया नहीं गया है या इतना छोटा समय दिखाया गया है (शायद 0.2 सेकंड)

समस्या क्या है?

+0

क्या आप कोई अपवाद छिपा रहे हैं? – Richie

+0

वास्तव में नहीं। जैसा कि मैंने कहा, संवाद विंडो इतनी कम समय देखी जा सकती है। वास्तव में इसे कम से कम 2 सेकंड देखा जाना चाहिए। –

उत्तर

23

हां, get()गणना करने के लिए आवश्यक होने पर प्रतीक्षा करता है, और फिर इसके परिणाम को पुनर्प्राप्त करता है। इसका मतलब है कि आप अपने यूआई थ्रेड को अवरुद्ध कर रहे हैं, परिणाम की प्रतीक्षा कर रहे हैं।

समाधान: get

आमतौर पर न करें, उसकी आप postExecute में एक समारोह (कॉलबैक) कॉल करेंगे।

+2

नमूना कार्यान्वयन के लिए http://stackoverflow.com/questions/3291490/common-class-for-asynctask-in-android देखें – rds

+0

समझ गया! नमूना के लिए धन्यवाद, इसे हल किया लेकिन अभी भी विभिन्न विषय के लिए समस्याएं हैं। –

+2

लेकिन अगर मैं AsyncTask के वापसी मूल्य का उपयोग करना चाहता हूं और वापसी मूल्य के आधार पर मैं नया यूआरएल कॉल करने के लिए wannt तो मैं इसके लिए क्या कर सकता हूं ?? मुझे लगता है कि इस तरह से हमें इसका उपयोग करना होगा यदि इसके बिना कोई विकल्प है तो कृपया मुझे मदद करें – PankajAndroid

-2

इस तरह runOnUiThread उपयोग करके देखें:

  runOnUiThread(new Runnable(){ 
      public void run() { 
       dialog.show(); 
       }});  

एक AsyncTask पर कुछ चल रहा है इसका मतलब है कि इसकी तो आम तौर पर आप संचालकों और सामान जो मैं आमतौर पर दूर रहने के बिना Async तरीकों अंदर से ui आपरेशन चलाने नहीं कर सकते UIthread से दूर चल रहे से। मैं अपनी कक्षा में एक चर के रूप में एक प्रगति Dialog बनाकर इस तरह के समाधान को भी संभालता हूं ताकि यह पूरे वर्ग में दिखाई दे। मैं फिर अपने asynctask से पहले प्रगतिशीलता को बुलाता हूं और उसके बाद से पूरे वर्ग में दिखाई देता है। मैं ऑनस्टोस्ट (

+0

यूआई थ्रेड पर 'onPreExecute' और' onPostExecute' दोनों चलाए जाते हैं। 'doInBackground' एकमात्र चीज है जो नहीं है। –

+0

@ जेकवार्टन मुझे लगता है कि वे केवल यूआई थ्रेड पर डेटा वापस कर देते हैं और उस पर नहीं चलते हैं लेकिन मैं गलत हो सकता हूं ..... मेरे पास अभी तक एंड्रॉइड दस्तावेज लाइन के लिए याद नहीं है लाइन –

+0

मैंने पहले ही यह कोशिश की है, काम नहीं किया । फिर भी धन्यवाद। –

4

में अगर मैं आपका प्रश्न सही ढंग से समझता हूं, तो आपको ProgressDialog में अपने AsyncTask की प्रगति को अपडेट करने की आवश्यकता है और यह वर्तमान में काम नहीं कर रहा है। तो कुछ चीजें ध्यान दें: मुझे यकीन नहीं है कि आप .get() के साथ क्या हासिल करने का प्रयास कर रहे हैं लेकिन मुझे लगता है कि आप प्रगति प्रदर्शित करना चाहते हैं।

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

public class myAsync extends AsyncTask<String, Integer, List> { 

    String message; // for dialog message 
    ProgressDialog progress; 
    Intent myIntent; 
    Context ctx; 

    public myAsync(String message, Context ctx) { 
    this.message = message; 
    this.ctx = ctx; 
    progress = new ProgressDialog(ctx); 
    } 

    @Override 
    protected void onPreExecute() { 
    // Runs on the UI thread 
    progress.setMessage(message); 
    progress.setIndeterminate(true); 
    progress.setCancelable(false); 
    progress.show();  
    } 

    @Override 
    protected List doInBackground(String... params) { 
    // Runs in the background thread 
    // publish your progress here!! 
    int prog = 5; // This number will represent your "progress" 
    publishProgress(prog); 
    return anyList; 
    } 


    protected void onProgressUpdate(Integer... progress) { 
    // Runs in the UI thread 
    // This method will fire (on the UI thread) EVERYTIME publishProgress 
    // is called. 
    Log.d(TAG, "Progress is: " +progress); 
    } 

    @Override 
    protected void onPostExecute(List result) { 
    // Runs in the UI thread 

    for (int i=0; i<result.size(); i++) { 
     Log.d(TAG, "List item: " + result.get(i)); 
    } 

    if(progress.isShowing()) 
     progress.dismiss(); 
    } 
} 
+0

'get' के साथ, वह स्पष्ट रूप से कार्य से परिणाम प्राप्त करना चाहता है, ताकि उसका इंटरफ़ेस – rds

+0

@rds अपडेट किया जा सके _dou_ कभी भी AsyncTask के संदर्भ में '.get' का उपयोग करेगा? इसलिए क्यों मेरा _assumption_ "मुझे यकीन नहीं है कि आप क्या हासिल करने की कोशिश कर रहे हैं ..." और फिर ओपी के प्रश्न की मेरी व्याख्या पर। –

+0

@ मार्विन, आपकी टिप्पणी के लिए सबसे पहले धन्यवाद। बस, मुझे एक वेब सर्वर से जेसन मिल रहा है। इस लेनदेन को करने के दौरान, बस progressdialog विंडोज़ दिखाना चाहते हैं, बस इतना ही। अगर मैं कॉल नहीं करता हूं।(), यह ठीक है। संवाद को बटन पर क्लिक करने के तुरंत बाद दिखाया गया है (बटन 'asminc ट्रिगर करेगा)। लेकिन जिस तरह से मुझे जेसन परिणाम भी चाहिए। जैसा कि मुझे पता है .get() विधि परिणाम देता है। जब मैंने प्राप्त करने का प्रयास किया, लेनदेन के दौरान संवाद विंडो बहुत कम समय दिखाया गया है। मुझे आशा है कि अब यह आसान है। –

15

कॉलिंग .get() बदल जाता है एक प्रभावी "SyncTask" में अपने AsyncTask के रूप में यह जब तक AsyncTask अपने संसाधन समाप्त होने के मौजूदा धागा (जो यूआई धागा होगा) प्रतीक्षा करनी पड़ती है। चूंकि अब आप यूआई थ्रेड को अवरुद्ध कर रहे हैं, ProgressDialog की .show() विधि पर कॉल को संवाद को स्वयं को स्क्रीन खींचने की अनुमति देने का मौका कभी नहीं मिलता है।

कॉल को हटाने से यह पृष्ठभूमि में ठीक से चलने की अनुमति देगा।

यदि कार्य पूरा होने के बाद आपको प्रोसेसिंग करने की आवश्यकता है तो मुझे सुझाव है कि आप इसे onPostExecute विधि में ही डाल दें या से Activity पर कॉलबैक का उपयोग करें।

+0

मुझे लगता है कि आप सही हैं लेकिन क्या आप इसे और समझा सकते हैं? कोई स्निपेट्स क्योंकि मुझे यकीन नहीं है कि onPostExecute से कॉलबैक का उपयोग कैसे करें। धन्यवाद। –

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