खोज…


परिचय

यदि आप ऑनक्रीट विधि कहते हैं, तो लोडर मेमोरी लीक को रोकने के लिए अच्छा विकल्प है। उदाहरण के लिए जब हम oncreate पद्धति में एसिंक्टस्क निष्पादित करते हैं और हम स्क्रीन को घुमाते हैं, तो गतिविधि फिर से हो जाएगी जो एक और AsyncTask को फिर से निष्पादित करेगा, इसलिए संभवतः लोडर की तरह समानांतर में एक साथ चलने वाले दो Asyntask जो पृष्ठभूमि प्रक्रिया को जारी रखेंगे, जिसे हमने पहले निष्पादित किया था।

पैरामीटर

कक्षा विवरण
LoaderManager एक या एक से अधिक लोडर उदाहरणों के प्रबंधन के लिए एक गतिविधि या फ्रैगमेंट से जुड़ा एक सार वर्ग।
LoaderManager.LoaderCallbacks लोडर मैनेजर के साथ बातचीत करने के लिए क्लाइंट के लिए कॉलबैक इंटरफ़ेस।
लोडर एक अमूर्त वर्ग जो डेटा के अतुल्यकालिक लोडिंग करता है।
AsyncTaskLoader सार लोडर जो काम करने के लिए एक AsyncTask प्रदान करता है।
CursorLoader AsyncTaskLoader का एक उपवर्ग जो ContentResolver पर सवाल उठाता है और एक कर्सर लौटाता है।

टिप्पणियों

एंड्रॉइड 3.0 में प्रस्तुत किया गया, लोडर एक गतिविधि या टुकड़े में अतुल्यकालिक रूप से डेटा लोड करना आसान बनाते हैं। लोडर में ये विशेषताएं हैं:

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

जब लोडर का उपयोग नहीं करना है

यदि आपको पृष्ठभूमि कार्यों को पूरा करने के लिए लोडर का उपयोग नहीं करना चाहिए। एंड्रॉइड लोडर्स को उन गतिविधियों / फ़्रैगमेंट्स के साथ नष्ट कर देता है जो वे संबंधित हैं। यदि आप कुछ कार्य करना चाहते हैं, जिन्हें पूरा होने तक चलाना है, तो लोडर का उपयोग न करें। आपको इसके बजाय इस तरह के सामान के लिए सेवाओं का उपयोग करना चाहिए।

बेसिक AsyncTaskLoader

AsyncTaskLoader एक अमूर्त Loader जो काम करने के लिए एक AsyncTask प्रदान करता है।

यहाँ कुछ बुनियादी कार्यान्वयन:

final class BasicLoader extends AsyncTaskLoader<String> {

    public BasicLoader(Context context) {
        super(context);
    }

    @Override
    public String loadInBackground() {
        // Some work, e.g. load something from internet
        return "OK";
    }

    @Override
    public void deliverResult(String data) {
        if (isStarted()) {
            // Deliver result if loader is currently started
            super.deliverResult(data);
        }
    }

    @Override
    protected void onStartLoading() {
        // Start loading
        forceLoad();
    }

    @Override
    protected void onStopLoading() {
        cancelLoad();
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();
    }
}

आमतौर पर Loader को गतिविधि के onCreate() विधि के भीतर, या टुकड़े के onActivityCreated() के भीतर शुरू किया जाता है। इसके अलावा आमतौर पर गतिविधि या टुकड़ा LoaderManager.LoaderCallbacks इंटरफ़ेस:

public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks<String> {

    // Unique id for loader
    private static final int LDR_BASIC_ID = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initialize loader; Some data can be passed as second param instead of Bundle.Empty
        getLoaderManager().initLoader(LDR_BASIC_ID, Bundle.EMPTY, this);
    }

    @Override
    public Loader<String> onCreateLoader(int id, Bundle args) {
        return new BasicLoader(this);
    }

    @Override
    public void onLoadFinished(Loader<String> loader, String data) {
        Toast.makeText(this, data, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onLoaderReset(Loader<String> loader) {
    }
}

इस उदाहरण में, जब लोडर पूरा हो जाता है, तो परिणाम के साथ टोस्ट दिखाया जाएगा।

कैश के साथ AsyncTaskLoader

एक ही डेटा के कई लोडिंग से बचने के लिए लोड किए गए परिणाम को कैश करना एक अच्छा अभ्यास है।
कैश को onContentChanged() अमान्य करने के लिए onContentChanged() को बुलाया जाना चाहिए। यदि लोडर पहले से ही चालू हो गया है, तो forceLoad() को कॉल किया जाएगा, अन्यथा (यदि रोका हुआ राज्य में लोडर) लोडर takeContentChanged() चेक के साथ सामग्री परिवर्तन को समझने में सक्षम होगा।

टिप्पणी: onContentChanged() को प्रक्रिया के मुख्य सूत्र से बुलाया जाना चाहिए।

Javadocs के बारे में कहते हैं

वर्तमान ध्वज को इंगित करें कि क्या लोडर की सामग्री बदल गई थी, जबकि इसे रोक दिया गया था। यदि यह था, तो सच लौटा दिया गया है और झंडा साफ हो गया है।

public abstract class BaseLoader<T> extends AsyncTaskLoader<T> {

    // Cached result saved here
    private final AtomicReference<T> cache = new AtomicReference<>();

    public BaseLoader(@NonNull final Context context) {
        super(context);
    }

    @Override
    public final void deliverResult(final T data) {
        if (!isReset()) {
            // Save loaded result
            cache.set(data);
            if (isStarted()) {
                super.deliverResult(data);
            }
        }
    }

    @Override
    protected final void onStartLoading() {            
        // Register observers
        registerObserver();

        final T cached = cache.get();    
        // Start new loading if content changed in background
        // or if we never loaded any data
        if (takeContentChanged() || cached == null) {
            forceLoad();
        } else {
            deliverResult(cached);
        }
    }

    @Override
    public final void onStopLoading() {
        cancelLoad();
    }

    @Override
    protected final void onReset() {
        super.onReset();
        onStopLoading();
        // Clear cache and remove observers
        cache.set(null);
        unregisterObserver();
    }

    /* virtual */
    protected void registerObserver() {
        // Register observers here, call onContentChanged() to invalidate cache
    }

    /* virtual */
    protected void unregisterObserver() {
        // Remove observers
    }
}

पुन: लोड

अपने पुराने डेटा को अमान्य करने के लिए और मौजूदा लोडर को पुनरारंभ करने के लिए आप पुनः restartLoader() विधि का उपयोग कर सकते हैं:

private void reload() {
    getLoaderManager().reastartLoader(LOADER_ID, Bundle.EMPTY, this);
}

एक बंडल का उपयोग कर मापदंडों को पास करें

आप बंडल करके पैरामीटर पास कर सकते हैं:

Bundle myBundle = new Bundle();
myBundle.putString(MY_KEY, myValue);

OnCreateLoader में मान प्राप्त करें:

@Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
    final String myParam = args.getString(MY_KEY);
    ...
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow