Zoeken…


Invoering

Loader is een goede keuze om geheugenlekken te voorkomen als u gegevens op de achtergrond wilt laden wanneer de oncreate-methode wordt aangeroepen. Als we bijvoorbeeld Asynctask uitvoeren in de oncreate-methode en we roteren het scherm zodat de activiteit opnieuw wordt gemaakt, waardoor een andere AsyncTask opnieuw wordt uitgevoerd, dus waarschijnlijk twee Asyntask die tegelijkertijd parallel lopen in plaats van als een lader die het achtergrondproces dat we eerder hebben uitgevoerd, zal voortzetten.

parameters

Klasse Beschrijving
LoaderManager Een abstracte klasse die is gekoppeld aan een activiteit of fragment voor het beheren van een of meer Loader-instanties.
LoaderManager.LoaderCallbacks Een terugbelinterface voor een client om te communiceren met de LoaderManager.
lader Een abstracte klasse die gegevens asynchroon laadt.
AsyncTaskLoader Abstracte lader die een AsyncTask biedt om het werk te doen.
CursorLoader Een subklasse van AsyncTaskLoader die de ContentResolver opvraagt en een cursor retourneert.

Opmerkingen

Geïntroduceerd in Android 3.0, maken laders het gemakkelijk om asynchroon gegevens in een activiteit of fragment te laden. Laders hebben deze kenmerken:

  • Ze zijn beschikbaar voor elke activiteit en elk fragment .
  • Ze zorgen voor asynchrone laden van gegevens.
  • Ze controleren de bron van hun gegevens en leveren nieuwe resultaten wanneer de inhoud verandert.
  • Ze maken automatisch opnieuw verbinding met de cursor van de laatste lader wanneer ze opnieuw worden gemaakt na een configuratiewijziging. Ze hoeven dus niet opnieuw naar hun gegevens te zoeken.

Wanneer laders niet te gebruiken

Gebruik geen laders als u de achtergrondtaken nodig hebt om te voltooien. Android vernietigt laders samen met de activiteiten / fragmenten waartoe ze behoren. Als u enkele taken wilt uitvoeren die tot voltooiing moeten worden uitgevoerd, gebruik dan geen laders. Gebruik in plaats daarvan services voor dit soort dingen.

Basic AsyncTaskLoader

AsyncTaskLoader is een abstracte Loader die een AsyncTask biedt om het werk te doen.

Hier wat basisimplementatie:

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();
    }
}

Meestal wordt Loader geïnitialiseerd binnen de onCreate() -methode van de activiteit of binnen de onActivityCreated() het fragment. Meestal implementeert activiteit of fragment ook LoaderManager.LoaderCallbacks interface:

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) {
    }
}

In dit voorbeeld wordt, wanneer de lader is voltooid, toast met resultaat getoond.

AsyncTaskLoader met cache

Het is een goede gewoonte om het geladen resultaat in de cache te plaatsen om te voorkomen dat dezelfde gegevens meerdere keren worden geladen.
Om cache ongeldig te maken onContentChanged() moet onContentChanged() worden aangeroepen. Als de lader al is gestart, wordt forceLoad() aangeroepen, anders (als de lader in de stopstand staat) kan lader de inhoudsverandering begrijpen met de controle takeContentChanged() .

Opmerking: onContentChanged() moet worden aangeroepen vanuit de onContentChanged() van het proces.

Javadocs zegt over takeContentChanged ():

Neem de huidige vlag die aangeeft of de inhoud van de lader was gewijzigd terwijl deze was gestopt. Als dit het geval was, wordt true geretourneerd en wordt de vlag gewist.

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
    }
}

Het herladen

Om uw oude gegevens ongeldig te maken en de bestaande lader opnieuw te starten, kunt u de methode restartLoader() gebruiken:

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

Geef parameters door met een bundel

U kunt parameters doorgeven per bundel:

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

Haal de waarde op 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow