¿Cuál es el alcance de un carroManager?
Pregunta
Al identificar los cargadores en su LoadManager, utiliza ID únicos. Estoy preguntando qué tan únicos deben ser esas identificaciones.
¿Cada actividad y fragmento tienen su propio carroManager? ¿Los fragmentos usan el carroManager de la actividad a la que se les une? ¿Hay solo un carroManager que posee la aplicación?
Puntos de bonificación Si puede decirme cómo es posible cambiar qué carroManager está utilizando. Si quiero que todos los fragmentos en mi actividad usen el mismo loadermanager (algunos de ellos están extrayendo los mismos datos y compartir cargadores serían buenos), ¿es eso posible?
Solución
Actualmente estoy portando mi aplicación al paquete de compatibilidad de Android (principalmente para cursorloader y fragmentos). Actualmente estoy tratando de compartir un cargador de cursor entre dos fragmentos para ahorrar una consulta a mi ContentProvider. ¡Bienvenido a mi mundo! ;)
Un caso de uso simple:
− DummyActivity extiende fragmentActivity / log.d (constants.logtag, "dummyActivity.Oncreate" + getSupportloadManager (). ToString ());
− DataFragment extiende los implementos de fragmentos Loadermanager.loaderCallbacks / log.d (constants.logtag, "dataFragment.Oncreate" + getLoadManager (). ToString ());
- ReportFragment extiende los implementos de fragmentos Loadermanager.loaderCallbacks / log.d (constants.logtag, "ReportFragment.Oncreate" + getLoadManager (). ToString ());
DummyActivity instancia el DataFragment y el posterior instancia el InformeFragment. La salida de logCat muestra las diferentes direcciones para cada carga de carga. Como primera conclusión, cada fragmento parece tener una carga de carga adecuada ...
Continuaré y actualizaré si puedo responder a su pregunta (nuestra;)). Si ha hecho algún progreso, comparta su valioso conocimiento.
Actualizar:
Supongo que las ID de cargador solo se asocian con un alcance local de un carroManager para un fragmento específico para permitir que varios cargadores locales se asocien con el fragmento (por lo que puede devolver un cargador diferente en OnCreateloader en función del ID int arg y el InitLoader llamadas).
Hasta ahora logré "reutilizar" un cargador (... o no):
- Primero, he habilitado la depuración de LoadERManager con getSupportLoaderManager().enableDebugLogging(true);
en la dumituda onCreate
método.
- Entonces he llamado getActivity().getSupportLoaderManager().initLoader(78, null, this);
desde el onCreate
Métodos de DataFragment e ReportFragment.
- DataFragment expone el CursorLoader creado por el onCreateLoader
Método a través de un setter en un miembro privado McursorLoader.
- el informe de informes 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 a partir de la dumituda onCreate
Método (diferente del caso de uso descrito, pero eso no cambia nada al problema en el que estamos trabajando). Desafortunadamente, el cargador es reasignado al último fragmento que lo llama (aquí ReportFragment) ... y DataFragment.onloadFinished nunca se llama. Como consecuencia, el informe de informes se ve bien, pero el fragmento de datos no está actualizado ya que la actualización se llama desde el onLoadFinished
de esta clase.
Supongo que hay una llamada subyacente no registrada y luego una llamada de registro en el CursorLoader.
Continuará…
Otros consejos
Sí. Funcionó para mí. Tengo 3 fragmentos diferentes en un cajón de navegación donde los mismos datos están poblados en diferentes vistas de list. (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 de cargador en todos los fragmentos.
Fragmento1:
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);
}
}
Use la misma ID para el fragmento2:
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 esta la forma correcta? ¿Existe un mejor método para usar un cargador común para múltiples fragmentos?