Wie kann ich einen einfachen AsyncTaskLoader implementieren?

In einer meiner letzten SO-Fragen schlug jemand vor, dass ich Loader für meine Lösung verwende. Also hier versuche ich zu verstehen, wie man einen einfachen AsyncTaskLoader

Hier ist was ich komme:

  • IllegalArgumentException-Parameter muss ein Abkömmling dieser Ansicht in ViewGroup.offsetRectBetweenParentAndChild sein
  • Auf der Suche nach einem guten Terminkicker für Android
  • Upload fehlgeschlagen Sie müssen einen anderen Versionscode für Ihre APK verwenden, da Sie bereits einen mit Versionscode 2 haben
  • Abrechnung: isBillingSupported immer nicht verfügbar
  • Android Emulator Wie benutzt man telnet localhost 5554?
  • Android Studio 1.0 und Fehler "Bibliotheksprojekte können nicht ApplicationId gesetzt werden"
  •  public class Scraper extends AsyncTaskLoader<List<Event>> { List<Event> lstEvents; public Scraper(Context context) { super(context); } public List<Event> loadInBackground() { //This is where I will do some work and return the data } } 

    Das ist alles, was ich herausgefunden habe. Ich lese die docs für den AyncTaskLoader aber ich habe niemals so etwas kryptisch und unordentlich wie es gekommen. Es gibt eine Million Methoden, die alle gegenseitig gegenseitig sind und sie anschauen, es ist unmöglich, daraus abzuleiten, die Reihenfolge, in der sie aufgerufen werden, oder sogar, ob sie überschrieben und aufgerufen werden sollen. Der Lebenszyklus dieser Aufgabe ist ein verdammter Albtraum.

    Was ich suche, ist, einfach einige Daten zu kratzen und es zurückzugeben. Ich würde es auch gerne in einer Klassenvariable speichern, damit ich es das nächste Mal sofort zurückgibt, ohne dass ich alle Daten wieder kratzen muss.

    Ich habe keine offenen Cursor, Ströme oder so etwas, nur eine einfache Variable namens lstEvents (die vielleicht groß sein). Ich möchte nicht das Gedächtnis auslaufen und die Ressourcen verschwenden, also werde ich froh sein, wenn jemand erklären könnte, was ich brauche, um zu schließen und zu klären, wo und wann diese Aufgabe funktioniert.

    Wo soll ich die Daten in die Klassenvariable speichern? Shoudl ich mache es am Ende meiner loadInBackground Methode oder soll ich das in der deliverResult Methode machen?

    In diesem einfachen Szenario gibt es Orte, die ich wirklich überprüfen muss, ob die Aufgabe abgebrochen wurde oder ob es zurückgesetzt wurde oder sollte ich einfach nicht diese Methoden überschreiben und den AsyncTaskLoader behandeln lassen.

    Ein Gerüstcode wäre hilfreich, wenn jemand weiß. Danke vielmals.

  • Android bekommt alle Länder auf Array Spinner
  • Einstellen einer maximalen Breite für LinearLayout
  • Finde alle Klassen in einem Paket in Android
  • Was ist "BasicDream" in Android ICS?
  • Veröffentlichen Sie die Google Play über die Befehlszeile
  • RecyclerAnzeige vergrößern / verkleinern
  • 3 Solutions collect form web for “Wie kann ich einen einfachen AsyncTaskLoader implementieren?”

    In einer meiner letzten SO-Fragen schlug jemand vor, dass ich Loader für meine Lösung verwende.

    Das war wohl kein guter Vorschlag.

    Der Lebenszyklus dieser Aufgabe ist ein verdammter Albtraum.

    Nicht zu erwähnen, dass der Loader Vertrag darauf hindeutet, dass Sie in der Lage sein werden, dynamisch Änderungen in den Daten zu erkennen und Updates automatisch an die mit dem Loader liefern, was für einen ContentProvider einfach ist, schwierig für andere On-Device-Läden und nicht Besonders praktisch für Szenarien wie deine.

    Ehrlich gesagt würde ich einfach eine AsyncTask und es gut nennen.

    ContentProvider SharedPreferences , können Sie sich die Loader Implementierungen anschauen, die ich für SQLite-Datenbanken (sans ContentProvider ) und SharedPreferences als Beispiele für benutzerdefinierte Loader gemacht habe. Die einzigen Methoden, die Sie implementieren müssen , sind loadInBackground() und onStartLoading() . Sie können deliverResult() benötigen, wenn die eingebaute Implementierung unzureichend ist – in Ihrem Fall vermute ich, dass der eingebaute Eins gut geht. Sie können in einige der anderen Methoden hinzufügen, wie Sie in meinem AbstractCursorLoader , obwohl ich wieder einmal vermute, dass Sie sie nicht brauchen werden.

    Gibt es Orte, die ich wirklich überprüfen muss, ob die Aufgabe abgebrochen wurde oder ob es zurückgesetzt wurde oder sollte ich einfach nicht diese Methoden überschreiben und den AsyncTaskLoader damit behandeln lassen.

    Beginnen Sie mit der AsyncTaskLoader behandeln Sie sie nur, wenn Sie feststellen, dass Sie sie aus AsyncTaskLoader Grund benötigen.

    Zusätzlich zu all den guten Informationen von CommonsWare's Antwort, hier ist noch etwas zu beachten. Bei der Implementierung von AsyncTaskLoader müssen Sie forceLoad() irgendwo auf deinem Loader oder auf deiner Unterklasse von AsyncTaskLoader . Andernfalls wird deine loadInBackground() Methode nicht in meine Erfahrung aufgerufen.

    Aus meinem Verständnis der Dokumentation kann ein Loader auf seine Ergebnisse in einer Member-Variable hängen, wie Sie in Ihrer Frage ausgespült haben. Dann können Sie onStartLoading() überschreiben und auf Ihre zwischengespeicherte Liste der Ergebnisse überprüfen. Wenn die Liste null ist, kann der Loader forceLoad() auf sich selbst aufrufen.

    Beachten Sie auch, dass, wenn Sie am Ende implementieren Caching Ergebnisse, bewusst sein, dass loadInBackground() auf einem anderen Thread aufgerufen wird, so dass Sie vielleicht den Zugriff auf alle Member-Variablen synchronisieren möchten.

    Es ist etwas spät, aber vielleicht nützlich für andere, die diese Frage lesen. Dies ist eine Realisierung von AsyncTaskLoader:

     public class EventListLoader extends AsyncTaskLoader<List<Event>> { private List<Event> events; public EventListLoader(Context context) { super(context); events = new ArrayList<Event>(); } @Override public List<Event> loadInBackground(){ //"Simply scrape some data and return it" as a list of events here. } @Override public void deliverResult(List<Event> data) { if (isReset()) { releaseResources(events); return; } List<Event> oldData = events; events = data; if (isStarted()) super.deliverResult(data); releaseResources(oldData); } @Override protected void onStartLoading() { if (events != null && !events.isEmpty()) deliverResult(events); if (takeContentChanged() || events == null || events.isEmpty()) forceLoad(); } @Override protected void onStopLoading() { super.onStopLoading(); cancelLoad(); } @Override public void onCanceled(List<Event> data) { super.onCanceled(data); releaseResources(events); } @Override protected void onReset() { super.onReset(); onStopLoading(); releaseResources(events); } private void releaseResources(List<Event> data) { if (data!= null && !data.isEmpty()) data.clear(); } } 

    Verwenden Sie es innerhalb von ListFragment als:

     public class EventsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Event>> { private static final int LOADER_ID = 0; ... @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ... setListAdapter(new EventListAdapter()); if (savedInstanceState == null) getLoaderManager().initLoader(LOADER_ID, null, this); else getLoaderManager().restartLoader(LOADER_ID, null, this); } @Override public Loader<List<Event>> onCreateLoader(int id, Bundle args) { return new EventLoader(getActivity()); } @Override public void onLoadFinished(Loader<List<Event>> loader, List<Event> data) { ((EventListAdapter) getListAdapter()).setData(data); invalidateActionMode(); //Only if Contextual Action Bar (CAB) is used. } @Override public void onLoaderReset(Loader<List<Event>> loader) { ((EventListAdapter) getListAdapter()).clearData(); } 

    Können wir eine Ereignisliste (aus lokaler Datenbank oder Internet) als ListFragment (zB) einfügen und anzeigen, wenn wir EventListAdapter als:

     public class EventListAdapter extends BaseAdapter { protected List<Event> mItems = new ArrayList<>(); @Override public boolean isEnabled(int position) { return true; } @Override public boolean hasStableIds() { return true; } @Override public int getCount() { return mItems.size(); } @Override public Object getItem(int position) { return mItems.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ... } public void setData(List<Event> items){ mItems.clear(); mItems.addAll(items); notifyDataSetChanged(); } public void clearData(){ mItems.clear(); notifyDataSetChanged(); } } 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.