2012-04-16 14 views
5

से मैं परिवर्तित कर दिया है मेरी AsyncTask एक AsyncTaskLoader को (ज्यादातर विन्यास बदलाव से निपटने के लिए)। मैं एक TextView मैं एक प्रगति स्थिति के रूप में उपयोग कर रहा हूँ और AsyncTask में onProgressUpdate उपयोग कर रहा था इसे अद्यतन करने के लिए है। यह दिखता है नहीं AsyncTaskLoader की तरह एक बराबर है, तो loadInBackground (AsyncTaskLoader से) के दौरान मैं इस का उपयोग कर रहा:अद्यतन यूआई एक AsyncTaskLoader

getActivity().runOnUiThread(new Runnable() { 
    public void run() { 
     ((TextView)getActivity().findViewById(R.id.status)).setText("Updating..."); 
    } 
}); 

मैं जिसके कारण मैं getActivity() उपयोग कर रहा हूँ एक Fragment में यह उपयोग कर रहा हूँ,। कॉन्फ़िगरेशन परिवर्तन होने पर, स्क्रीन अभिविन्यास को बदलने की तरह, यह बहुत अच्छी तरह से काम करता है। मेरे AsyncTaskLoader चलता रहे (जिसके कारण मैं एक AsyncTaskLoader उपयोग कर रहा हूँ), लेकिन runOnUiThread को छोड़ दिया करने के लिए लगता है।

यह सुनिश्चित नहीं है कि इसे क्यों छोड़ा जा रहा है या यदि यह AsyncTaskLoader से UI को अपडेट करने का सबसे अच्छा तरीका है।

अद्यतन:

मैं एक AsyncTask को वापस लौटाते समय के रूप में यह बेहतर यूआई अद्यतन के लिए अनुकूल लगता है समाप्त हो गया। इच्छा है कि वे के साथ AsyncTaskLoader के साथ क्या काम कर सकते हैं।

उत्तर

4

यह वास्तव में संभव है। आपको अनिवार्य रूप से AsyncTaskloader को उप-वर्ग करने की आवश्यकता है और publishMessage() विधि लागू करें, जो का उपयोग किसी भी कक्षा में प्रगति संदेश देने के लिए करेगा जो ProgressListener (या जो भी आप इसे कॉल करना चाहते हैं) इंटरफ़ेस लागू करता है। एक उदाहरण के लिए

डाउनलोड इस: http://www.2shared.com/file/VW68yhZ1/SampleTaskProgressDialogFragme.html (मुझे संदेश अगर यह ऑफ़लाइन चला जाता है) - इस http://habrahabr.ru/post/131560/

+0

मुझे लगता है कि यह एक बहुत चालाक हैक है। मैंने इसके बारे में कभी सोचा नहीं। मैं लोडर का उपयोग करके अपने प्रगति अद्यतन भेजने का तरीका ढूंढ रहा था। मैं इसे आज़मा दूंगा और आपको बता दूंगा। मुझे लगता है कि आपका समाधान काम करना चाहिए !! – douggynix

+0

लिंक खराब हो गया प्रतीत होता है। [यहां] (https://yadi.sk/d/qovznXrpUbbum) एक कामकाजी है (मुझे लगता है कि यह वही है)। – EmmanuelMess

0

जिस श्रेणी में आप LoaderManager.LoaderCallback (संभवतः आपकी गतिविधि) को लागू करते हैं, उसमें onLoadFinished() विधि है जिसे आपको ओवरराइड करना होगा। यह वापस आता है जब AsyncTaskLoader लोडिंग समाप्त हो गया है।

+1

मुझे गलत हो सकता है लेकिन 'AsLcTaskLoader' लोड होने पर' ऑनलोड लोड नहीं किया गया है '? बिल्कुल सही नहीं है कि यह मेरे मुद्दे को कैसे संबोधित करता है, लेकिन मैं 'AsyncTaskLoaders' के लिए नया हूं इसलिए मुझे कुछ याद आ रहा है। 'AsLcogress' में 'ऑन-प्रोग्रेसअपडेट' के बराबर 'ऑनलोड लोड' है? –

+0

यह 'onPostExecute' –

+2

के बराबर है जो मैं नहीं ढूंढ रहा हूं। मुझे 'onProgressUpdate' के समतुल्य की आवश्यकता है, इसलिए पृष्ठभूमि स्थिति चल रही है, इसलिए मैं एक स्थिति दिखा सकता हूं। मुझे नहीं लगता कि 'AsyncTaskLoader' में एक है। –

1

मेरे अपने प्रश्न का उत्तर देना, लेकिन मैं क्या बता सकता से, AsyncTaskLoader सबसे अच्छा अगर आप यूआई अद्यतन करने की आवश्यकता का उपयोग नहीं है।

4

ईएमएम के आधार पर किया गया था ... यदि आप ऐसा करने नहीं दिया जाना चाहिए।

क्योंकि अभिभावक वर्ग के लिए अदृश्य संदर्भ संग्रहीत करके अज्ञात वर्ग कैसे अभिभावक वर्ग विधि या फ़ील्ड का उपयोग करता है।

उदाहरण के लिए

आपके पास एक Activity:

public class MyActivity 
    extends Activity 
{ 
    public void someFunction() { /* do some work over here */ } 

    public void someOtherFunction() { 
     Runnable r = new Runnable() { 
      @Override 
      public void run() { 
       while (true) 
        someFunction(); 
      } 
     }; 
     new Thread(r).start(); // use it, for example here just make a thread to run it. 
    } 
} 

संकलक वास्तव में कुछ इस तरह उत्पन्न करेगा:

private static class AnonymousRunnable { 
    private MyActivity parent; 
    public AnonymousRunnable(MyActivity parent) { 
     this.parent = parent; 
    } 

    @Override 
    public void run() { 
     while (true) 
      parent.someFunction(); 
    } 
} 

तो, जब आपके माता-पिता Activity नष्ट कर देता है (विन्यास परिवर्तन के कारण, उदाहरण के लिए) , और आपकी अनाम कक्षा अभी भी मौजूद है, पूरी गतिविधि जीसी-एड नहीं हो सकती है। (क्योंकि किसी के पास अभी भी एक संदर्भ है।)

जो एक स्मृति लीक बनता है और आपके एप को लिम्बो जाओ !!!

अगर यह मैं था, मैं इस तरह लोडर के लिए "onProgressUpdate()" को क्रियान्वित करेगी:

public class MyLoader extends AsyncTaskLoader<Something> { 
    private Observable mObservable = new Observable(); 
    synchronized void addObserver(Observer observer) { 
     mObservable.addObserver(observer); 
    } 
    synchronized void deleteObserver(Observer observer) { 
     mObservable.deleteObserver(observer); 
    } 

    @Override 
    public void loadInBackground(CancellationSignal signal) 
    { 
     for (int i = 0;i < 100;++i) 
      mObservable.notifyObservers(new Integer(i)); 
    } 
} 

और अपने Activity कक्षा में

public class MyActivity extends Activity { 
    private Observer mObserver = new Observer() { 
     @Override 
     public void update(Observable observable, Object data) { 
      final Integer progress = (Integer) data; 
      mTextView.post(new Runnable() { 
       mTextView.setText(data.toString()); // update your progress.... 
      }); 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreated(savedInstanceState); 

     MyLoader loader = (MyLoader) getLoaderManager().initLoader(0, null, this); 
     loader.addObserver(mObserver); 
    } 

    @Override 
    public void onDestroy() { 
     MyLoader loader = (MyLoader) getLoaderManager().getLoader(0); 
     if (loader != null) 
      loader.deleteObserver(mObserver); 
     super.onDestroy(); 
    } 
} 

onDestroy() दौरान deleteObserver() के लिए याद महत्वपूर्ण है , इस प्रकार लोडर हमेशा आपकी गतिविधि का संदर्भ नहीं रखता है। (लोडर शायद आपके Application जीवन चक्र के दौरान जिंदा आयोजित किया जाएगा ...)

+1

ऐसा लगता है कि आप पर्यवेक्षक पर एक सेट चेंज() खो रहे हैं, है ना? – Maxr1998

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