Qual è la portata di un LoaderManager?
Domanda
Quando l'individuazione di pale in vostro LoaderManager, si utilizza ID univoci. Sto chiedendo a come unico tali ID devono essere.
fa ogni attività e la frammento dispone di un proprio LoaderManager? Non frammenti usano il LoaderManager della attività che stanno attaccati? C'è un solo LoaderManager che l'applicazione possiede?
I punti di bonus se si può dirmi come è possibile cambiamento che LoaderManager si sta utilizzando. Se voglio ogni frammento della mia attività di utilizzare lo stesso LoaderManager (alcuni di loro stanno tirando gli stessi dati e la condivisione di Pale sarebbe bello), è possibile?
Soluzione
Attualmente sto porting la mia domanda per il pacchetto di compatibilità di Android (principalmente per CursorLoader e frammenti). Attualmente sto cercando di condividere un CursorLoader tra i due frammenti di risparmiare una query al mio ContentProvider. Benvenuto nel mio mondo! ;)
Un semplice caso d'uso:
- DummyActivity estende FragmentActivity / Log.d (. Constants.LOGTAG, "DummyActivity.onCreate" + getSupportLoaderManager () toString ());
- DataFragment estende utensileria Frammento LoaderManager.LoaderCallbacks / Log.d (. Constants.LOGTAG, "DataFragment.onCreate" + getLoaderManager () toString ());
- ReportFragment estende utensileria Frammento LoaderManager.LoaderCallbacks / Log.d (. Constants.LOGTAG, "ReportFragment.onCreate" + getLoaderManager () toString ());
DummyActivity instanciates il DataFragment e la successiva instanciates il ReportFragment. L'output mostra logcat differenti indirizzi per ciascun LoaderManager. Come prima conclusione, ogni frammento sembra avere una corretta LoaderManager ...
I continui e aggiornamento se posso rispondere alla tua (il nostro;)) domanda. Se è stato fatto alcun progresso, si prega di condividere le tue conoscenze preziose.
Aggiornamento:
mia ipotesi è che gli ID caricatore sono associati solamente con un ambito locale di un LoaderManager per un frammento specifico per abilitare diverse pale locali da associare con il frammento (modo da poter tornare un caricatore diverso onCreateLoader basato sul int id arg e le chiamate initLoader).
Finora sono riuscito a "riutilizzo" di un Loader (... oppure no):
-. In primo luogo, ho permesso LoaderManager debug con getSupportLoaderManager().enableDebugLogging(true);
nel metodo DummyActivity onCreate
-. Poi ho chiamato getActivity().getSupportLoaderManager().initLoader(78, null, this);
dai metodi onCreate
sia DataFragment e ReportFragment
-. DataFragment espone il CursorLoader creato dal metodo onCreateLoader
tramite un setter su un membro privato mCursorLoader
-. Il onCreateLoader
ReportFragment restituisce il DataFragment CursorLoader (dopo aver ottenuto il Frammento con findFragmentByTag
)
Il filtrato (e leggermente offuscato) logcat output:
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
I due frammenti sono aggiunti dal metodo DummyActivity onCreate
(diverso dal caso uso descritto, ma che cambia nulla al problema stiamo lavorando). Purtroppo, il caricatore è i riassegnati per l'ultimo frammento definendolo (qui ReportFragment) ... e DataFragment.onLoadFinished non viene mai chiamato. Di conseguenza, il ReportFragment sembra buono, ma la DataFragment non è up-to-date dal momento che l'aggiornamento viene chiamato dal onLoadFinished
di questa classe.
Si considera che v'è una chiamata sottostante unregister allora una chiamata registro sul CursorLoader.
Continua ...
Altri suggerimenti
Sì. Ha funzionato per me. Ho 3 diversi frammenti in un cassetto di navigazione dove lo stesso di dati viene popolata in diverse ListViews. (Tutti i frammenti sono una parte della stessa attività).
Il mio AsyncTaskLoader:
public class MyTaskLoader extends AsyncTaskLoader<HashMap<String, Integer>> {
public MyTaskLoader(Context context) {
super(context);
}
@Override
public HashMap<String, Integer> loadInBackground() {
...
return hashMap;
}
...
}
Utilizzare lo stesso Loader Id in tutti i frammenti.
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);
}
}
utilizzare lo stesso ID per 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);
}
}
L'adattatore deve essere inizializzato prima di inizializzare il caricatore. Funziona così lontano. Ma, è questo il modo giusto? Esiste un metodo migliore per l'utilizzo di un caricatore comune per più Frammenti?