LoaderManager
hat diese Methode restartLoader()
:Führt LoaderManager.restartLoader() immer zu einem Aufruf von onCreateLoader()?
public abstract Loader<D> restartLoader (int id, Bundle args, LoaderCallbacks<D> callback)
Startet eine neue oder neu startet einen vorhandenen Loader in diesem Manager registriert die Rückrufe zu ihm, und (wenn die Aktivität/Fragment wird zur Zeit gestartet) beginnt es zu laden. Wenn ein Loader mit derselben ID zuvor gestartet wurde, wird er automatisch zerstört, wenn der neue Loader seine Arbeit beendet hat. Der Rückruf wird geliefert, bevor der alte Lader zerstört wird.
Basierend auf the dev guide, erhalte ich die Idee, dass in der Tat, ein Aufruf an onCreateLoader
immer von restartLoader()
führen:
Neustarten eines Loader
...
zu verwerfen Ihre alte Daten verwenden Sie restartLoader(). Diese Implementierung von SearchView.OnQueryTextListener startet beispielsweise den Loader neu, wenn sich die Abfrage des Benutzers ändert. Der Lader muss neu gestartet werden, damit es die überarbeiteten Suchfilter verwenden kann, um eine neue Abfrage zu tun:
public boolean onQueryTextChanged(String newText) {
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
getLoaderManager().restartLoader(0, null, this);
return true;
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// NOTE: The Loader is instantiated with the user's query
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = Contacts.CONTENT_URI;
}
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ Contacts.DISPLAY_NAME + " != ''))";
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
Im Beispiel onCreateLoader
ist der einzige Ort, wo Informationen über die Anfrage des Benutzers an den Loader übergeben werden (auf Instantiierung). Aber die Dokumente werfen mich ab, indem sie sagen: Startet eine neue oder startet einen vorhandenen Loader neu.
Ich denke, OnCreateLoader wird auch auf dem UI-Thread aufgerufen ...! – Maarten
Ich bin interessiert, warum Sie denken, dass das der Fall ist? Das ist der Sinn von Loadern, asynchron mit einem ContentProvider/Datenquelle zu interagieren.Die lange laufende Aufgabe, die sonst die Benutzeroberfläche blockieren könnte, wird in onCreateLoader ausgeführt - der LoaderManager führt diesen Teil im Hintergrund aus. – NigelK
Ja, ja, der ['loadInBackBackground'] (https://developer.android.com/reference/android/content/AsyncTaskLoader.html) Teil eines AsyncTaskLoader läuft sicher auf einem Hintergrundthread, aber ich denke onCreateLoader ist auf dem UI-Thread: [Clients von Loadern sollten in der Regel alle Aufrufe an einen Loader aus dem Hauptthread ihres Prozesses ausführen (dh der Thread, in dem die Aktivitätsrückrufe und andere Dinge auftreten).] (Https://developer.android .com/reference/android/content/Loader.html) - Vergleichbar mit der Instantiierung einer 'AsyncTask', das war meine Argumentation. – Maarten