android - loaders - getloadermanager() deprecated
¿Cuál es el alcance de un LoaderManager? (2)
Al identificar los cargadores en su LoaderManager, utiliza identificadores únicos. Estoy preguntando qué tan únicas deben ser esas identificaciones.
¿Cada actividad y fragmento tiene su propio LoaderManager? ¿Los fragmentos usan el LoaderManager de la actividad a la que están vinculados? ¿Hay solo un LoaderManager que posee la aplicación?
Puntos de bonificación si puedes decirme cómo es posible cambiar qué LoaderManager estás usando. Si quiero que todos los fragmentos de mi Actividad utilicen el mismo LoaderManager (algunos de ellos están obteniendo los mismos datos y compartir los Cargadores estaría bien), ¿es posible?
Sí. Funciono para mi Tengo 3 fragmentos diferentes en un cajón de navegación donde los mismos datos se rellenan en diferentes ListViews. (Todos los fragmentos son parte de la MISMA actividad).
Mi AsyncTaskLoader:
public class MyTaskLoader extends AsyncTaskLoader<HashMap<String, Integer>> {
public MyTaskLoader(Context context) {
super(context);
}
@Override
public HashMap<String, Integer> loadInBackground() {
...
return hashMap;
}
...
}
Use la misma ID del cargador en todos los fragmentos.
Fragmento 1:
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);
}
}
Utilice la misma ID para 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);
}
}
El adaptador debe inicializarse antes de inicializar el cargador. Funciona hasta ahora. Pero, ¿es este el camino correcto? ¿Existe un método mejor para usar un cargador común para varios fragmentos?
Actualmente estoy portando mi aplicación al paquete de compatibilidad de Android (principalmente para CursorLoader y Fragmentos). Actualmente estoy intentando compartir un CursorLoader entre dos fragmentos para guardar una consulta en mi ContentProvider. ¡Bienvenido a mi mundo! ;)
Un caso de uso simple:
- DummyActivity extiende FragmentActivity / Log.d (Constants.LOGTAG, "DummyActivity.onCreate" + getSupportLoaderManager (). ToString ());
- DataFragment extiende Fragment implementa LoaderManager.LoaderCallbacks / Log.d (Constantes.LOGTAG, "DataFragment.onCreate" + getLoaderManager (). ToString ());
- ReportFragment extiende Fragment implementa LoaderManager.LoaderCallbacks / Log.d (Constants.LOGTAG, "ReportFragment.onCreate" + getLoaderManager (). ToString ());
DummyActivity crea una instancia del DataFragment y la instancia posterior crea el ReportFragment. La salida logcat muestra diferentes direcciones para cada LoaderManager. Como primera conclusión, cada fragmento parece tener un LoaderManager adecuado ...
Continuaré y actualizaré si puedo responder a su pregunta (nuestra;)). Si ha realizado algún progreso, comparta sus valiosos conocimientos.
Actualizar:
Supongo que los identificadores del cargador solo están asociados con el alcance local de un LoaderManager para un fragmento específico para permitir que varios cargadores locales se asocien con el fragmento (de modo que puede devolver un cargador diferente en onCreateLoader según el id int arg y el llamadas a initLoader).
Hasta ahora he logrado "reutilizar" un cargador (... o no):
- Primero, he habilitado la depuración de getSupportLoaderManager().enableDebugLogging(true);
con getSupportLoaderManager().enableDebugLogging(true);
en el método onCreate de onCreate
.
- Luego llamé a getActivity().getSupportLoaderManager().initLoader(78, null, this);
desde los métodos onCreate
tanto de DataFragment como de ReportFragment.
- DataFragment expone el CursorLoader creado por el método onCreateLoader
través de un configurador en un miembro privado de mCursorLoader.
- ReportFragment onCreateLoader
devuelve el DataFragment CursorLoader (después de recuperar el Fragmento con findFragmentByTag
).
La salida de logcat filtrada (y ligeramente ofuscada):
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
Los dos fragmentos se agregan del método DummyActivity onCreate
(diferente del caso de uso descrito, pero eso no cambia nada al problema en el que estamos trabajando). Desafortunadamente, el cargador se reasigna al último fragmento que lo llama (aquí, ReportFragment) ... y nunca se llama a DataFragment.onLoadFinished. Como consecuencia, ReportFragment se ve bien, pero DataFragment no está actualizado ya que la actualización se llama desde el onLoadFinished
de esta clase.
Supongo que hay una llamada de desregistro subyacente y luego una llamada de registro en el CursorLoader.
Continuará…