2015-08-06 7 views
12

Wie wird die abhängige Abfrage mit der LoaderManager API in Android bevorzugt geladen? Wie das Beste jetzt ich tun konnte mit etwas entlang der Linien von ist:Bevorzugte Methode zum Laden abhängiger Abfragen mit LoaderManager

@Override 
public void onCreate(Bundle savedInstanceState) { 
    getLoaderManager().initLoader(FIRST, null, this); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    switch (loader.getId()) { 
    case FIRST: 
     Bundle args = new Bundle(); 
     args.putInt(ID, somethingFromData(data)); 
     getLoaderManager().restartLoader(SECOND, args, this); 
     break; 

    case SECOND: 
     somethingElseFromData(data); 
     break; 
    } 
} 

Dies funktioniert die meiste Zeit, aber es stürzt schrecklich unter einem Sonderfall. Angenommen, ich starte eine zweite Aktivität oder drücke ein Fragment darüber, das die Daten von FIRST ändert. Wenn ich jetzt zurück zu der Aktivität/dem Fragment mit dem obigen Code navigiere, wird es zuerst mit den alten Daten FIRST und SECOND aktualisiert, und da FIRST initiiert SECOND ist, wird SECOND mit den neuen Daten neu geladen. Jetzt, da FIRST geändert wird, wird es erneut geladen, was wiederum eine weitere Belastung von SECOND verursacht.

Vor allem, wenn Sie zählen, dass das zusammen zu zwei Ladungen FIRST (ein altes und ein neues) und drei Ladungen SECOND (zwei alte und eine neue), die mindestens ein wenig verschwenderisch summiert. Das macht mir nichts aus, außer dass es mühsam ist zu debuggen, aber es scheint mir auch, sich nicht-deterministisch zu verhalten, weil man nicht weiß, welche Lasten zuerst beendet werden. Erhalte ich die neuen Daten für SECOND, wenn die Beziehung zwischen FIRST und SECOND geändert wird, oder werde ich mit den zwischengespeicherten Werten enden?

Ich weiß, dass ich das mildern kann, indem ich Punkte für den Neustart des zweiten Loaders halte, aber es muss einen besseren Weg geben, dies zu tun.

ein wenig zu verdeutlichen: Das Problem ist auffälligste wenn Zeilen in FIRST einen Verweis auf Zeilen in SECOND enthalten und nach der Rückführung in der Zeile (n) in FIRST auf die gleiche Zeile nicht darauf geladen (s) in SECOND wie vorher.

+0

Sie wissen zwar nicht, wie Ihre Daten aussehen, aber es riecht nach einer Datenbankansicht und hilft Ihnen möglicherweise, nur einen einzigen Loader zu verwenden. –

+0

Wäre das nicht dasselbe wie eine Unterabfrage, Join, etc, und wird diese auf die gleiche Weise aktualisiert wie andere Abfragen? I.e. 'SELECT first.id, second.id VOM ersten Join second ON first.id = second.first', wo das erste oder zweite bearbeitet wird, bekomme ich ein neues Update von' LoaderManager'? –

+0

Beispiel für was genau ich denke: http://sqlfiddle.com/#!5/3dd28/2/0 –

Antwort

1

Vorausgesetzt, dass das einzige, was Ihr erster Lader macht, effektiv Argumente für Ihren zweiten Lader vorzubereiten, sollten Sie Ihren eigenen AsyncTaskLoader ableiten und die gesamte Operation innerhalb eines Ladeprogramms durchführen.

This article enthält ein sehr detailliertes Beispiel für einen benutzerdefinierten AsyncTaskLoader, von dem Sie sich sicher an Ihre eigenen Bedürfnisse anpassen können. Sie sollten auch auf die CursorLoader source code für ein besseres Verständnis, wie Sie Ihre eigenen schreiben.

+0

Meinst du das hier: http://developer.android.com/reference/android/content/AsyncTaskLoader.html? Dein Link ist kaputt. Außerdem sieht es so aus, als hättest du die chinesische Seite oder so. –

+0

Ja, ich tat es! Es tut uns leid! Wenn ich das Android-Zeug google, kommt die chinesische Seite auf .. wörtlich keine Idee, warum – JoeyJubb

+0

Aus irgendeinem Grund tut es das auch für mich. Ich denke Google hat mit seinen Spracheinstellungen geschummelt. =) –