Frage

Wenn Sie Lader in Ihrem Loadermanager identifizieren, verwenden Sie eindeutige IDs. Ich frage nach, wie einzigartig diese IDs sein müssen.

Hat jede Aktivität und jedes Fragment einen eigenen Loadermanager? Verwenden Fragmente den Loadermanager der Aktivität, an die sie angebracht sind? Gibt es nur einen Loadermanager, den die Anwendung besitzt?

Bonuspunkte Wenn Sie mir sagen können, wie es möglich ist, welchen Loadermanager Sie verwenden. Wenn ich möchte, dass jedes Fragment in meiner Aktivität denselben Loadermanager verwendet (einige von ihnen ziehen dieselben Daten und teilen Lader gut), ist das möglich?

War es hilfreich?

Lösung

Ich portiere derzeit meine Anwendung auf das Android -Kompatibilitätspaket (hauptsächlich für Cursorloader und Fragmente). Ich versuche derzeit, einen Cursorloader zwischen zwei Fragmenten zu teilen, um eine Abfrage an meinen ContentProvider zu ersparen. Willkommen in meiner Welt! ;))

Ein einfacher Anwendungsfall:

- DummyActivity erweitert die Fragmentaktivität / log.d (Constants.logtag, "DummyActivity.oncreate" + getupportloaderManager (). ToString ());

- DataFragment erweitert Fragment implementiert loaderManager.loadecallbacks / log.d (constants.logtag, "dataFragment.oncreate" + getloaderManager (). ToString ());

- ReportFragment erweitert Fragment implementiert loaderManager.loadecallbacks / log.d (constants.logtag, "reportFagment.oncreate" + getloadermanager (). ToString ());

DummyActivity -Instanziierung der Datenfragment und die spätere Instanz der ReportFagment. Die Logcat -Ausgabe zeigt verschiedene Adressen für jeden Loadermanager an. Als erste Schlussfolgerung scheint jedes Fragment einen richtigen Loadermanager zu haben…

Ich werde fortfahren und aktualisieren, wenn ich auf Ihre (unsere;)) Frage antworten kann. Wenn Sie Fortschritte gemacht haben, teilen Sie bitte Ihr wertvolles Wissen mit.

Aktualisieren:

Meine Annahme ist, dass die Lader -IDs nur mit einem lokalen Bereich eines LoaderManager für ein bestimmtes Fragment verbunden sind, um mehrere lokale Lader mit dem Fragment zugeordnet zu werden (so können Sie einen anderen Lader in der On -Createloader basierend auf dem ID int arg und der zurückgeben. Initloader Anrufe).

Bisher habe ich es geschafft, einen Lader wieder zu "wiederverwenden" (... oder nicht):

- Zunächst habe ich LoaderManager -Debugging mit dem Debuggen mit getSupportLoaderManager().enableDebugLogging(true); in der Dummyaktivität onCreate Methode.

- Dann habe ich angerufen getActivity().getSupportLoaderManager().initLoader(78, null, this); von dem onCreate Methoden der Datenfragment- und ReportFagment.

- Datenfragment enthält den von der erstellten Cursorloader onCreateLoader Methode über einen Setter auf einem privaten Mitglied eines McUrorloaders.

- Die ReportFagment onCreateLoader Gibt den DataFragment Cursorloader zurück (nach dem Abrufen des Fragments mit findFragmentByTag).

Die gefilterte (und leicht verschleierte) Logcat -Ausgabe:

      DummyApp  D  DummyActivity.onCreate
      DummyApp  D  DataFragment.newInstance
      DummyApp  D  ReportFragment.newInstance
      DummyApp  D  DataFragment.onCreate
 LoaderManager  V  initLoader in LoaderManager{405a19d0 in SpecificAction{4059ee98}}: args=null
      DummyApp  D  DataFragment.onCreateLoader
 LoaderManager  V    Created new loader LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
      DummyApp  D  DataFragment.onCreate
      DummyApp  D  DataFragment.onActivityCreated
      DummyApp  D  ReportFragment.onCreate
 LoaderManager  V  initLoader in LoaderManager{405a19d0 in DummyActivity{4059ee98}}: args=null
 LoaderManager  V    Re-using existing loader LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
      DummyApp  D  SpecificActionReportFragment.onCreate
      DummyApp  D  SpecificActionReportFragment.onActivityCreated
 LoaderManager  V  Starting in LoaderManager{405a19d0 in DummyActivity{4059ee98}}
 LoaderManager  V    Starting: LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
 DummyProvider  D  query called
 DummyProvider  D  […]       
 DummyProvider  D  [end of query]
 LoaderManager  V  onLoadComplete: LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
 LoaderManager  V    onLoadFinished in CursorLoader{405a22e0 id=78}: CursorWrapperInner{405afb20}
      DummyApp  D  ReportFragment.onLoadFinished
      DummyApp  D  ReportFragment.displayActionReport
      DummyApp  D  DummyActivity.setReportViewsVisibility
      DummyApp  D  ReportFragment.setSaveReportImageViewVisibility

Die beiden Fragmente werden aus der Dummyaktivität hinzugefügt onCreate Methode (anders als der beschriebene Anwendungsfall, aber das ändert sich nichts in das Problem, an dem wir arbeiten). Leider ist der Lader neu zugewiesen Zu dem neuesten Fragment, der es nennt (hier reportFagment)… und dataFragment.onloadFinished wird nie aufgerufen. Infolgedessen sieht die ReportFagment gut aus, aber die Datenfragment ist nicht auf dem neuesten Stand, da das Update aus dem aufgerufen wird onLoadFinished dieser Klasse.

Ich gehe davon aus, dass es einen zugrunde liegenden Unregister -Anruf gibt, dann einen Registeranruf im Cursorloader.

Fortgesetzt werden…

Andere Tipps

Ja. Es hat für mich funktioniert. Ich habe 3 verschiedene Fragmente in einer Navigationsschublade, bei der die gleichen Daten in verschiedenen Listansicht gefüllt sind. (Alle Fragmente sind Teil der gleichen Aktivität).

Mein AsyncTaskloader:

public class MyTaskLoader extends AsyncTaskLoader<HashMap<String, Integer>> {

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

@Override
public HashMap<String, Integer> loadInBackground() {
...
return hashMap;
}

...
}

Verwenden Sie die gleiche Lader -ID in allen Fragmenten.

Fragment1:

public class Fragment1 extends BaseFragment implements LoaderManager.LoaderCallbacks<HashMap<String, Integer>> {
@Override
public void onCreate(Bundle savedInstanceState) {

//initialize adapter

getActivity().getSupportLoaderManager().initLoader(0, null, this);

}

@Override
public Loader<HashMap<String, Integer>> onCreateLoader(int arg0, Bundle arg1) {
    // TODO Auto-generated method stub

    return new MyTaskLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<HashMap<String, Integer>> arg0,
        HashMap<String, Integer> data) {
    // TODO Auto-generated method stub

    listAdapter.setData(data.keySet());

}

@Override
public void onLoaderReset(Loader<HashMap<String, Integer>> arg0) {
    // TODO Auto-generated method stub

    listAdapter.setData(null);
}
}

Verwenden Sie dieselbe ID für Fragment2:

public class Fragment2 extends BaseFragment implements LoaderManager.LoaderCallbacks<HashMap<String, Integer>> {
@Override
public void onCreate(Bundle savedInstanceState) {

//initialize adapter

getActivity().getSupportLoaderManager().initLoader(0, null, this);

}

@Override
public Loader<HashMap<String, Integer>> onCreateLoader(int arg0, Bundle arg1) {
    // TODO Auto-generated method stub

    return new MyTaskLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<HashMap<String, Integer>> arg0,
        HashMap<String, Integer> data) {
    // TODO Auto-generated method stub

    listAdapter.setData(data.keySet());

}

@Override
public void onLoaderReset(Loader<HashMap<String, Integer>> arg0) {
    // TODO Auto-generated method stub

    listAdapter.setData(null);
}
}

Der Adapter sollte vor der Initialisierung des Laders initialisiert werden. Funktioniert so weit. Aber ist das der richtige Weg? Gibt es eine bessere Methode, um einen gemeinsamen Lader für mehrere Fragmente zu verwenden?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top