studio oncreateloader loadermanager example android

android - oncreateloader - LoaderCallbacks.onLoadFinished no se llama si ocurre un cambio de orientaciĆ³n durante la ejecuciĆ³n de AsyncTaskLoader



loadermanager (2)

En realidad no es la llamada a initLoader() en onCreate() que lo está arreglando. Es la llamada a getLoaderManager() . En resumen, lo que sucede es que cuando se reinicia una actividad, ya conoce los cargadores. Intenta reiniciarlos cuando su actividad golpea en onStart() , pero luego golpea este código en FragmentHostCallback.doLoaderStart() *:

void doLoaderStart() { if (mLoadersStarted) { return; } mLoadersStarted = true; if (mLoaderManager != null) { mLoaderManager.doStart(); } else if (!mCheckedForLoaderManager) { mLoaderManager = getLoaderManager("(root)", mLoadersStarted, false); // WTF: Why aren''t we calling doStart() here?! } mCheckedForLoaderManager = true; }

Como aún no se llamó a getLoaderManager (), mLoaderManager es nulo. Por lo tanto, omite la primera condición y la llamada a mLoaderManager.doStart() .

Puede probar esto simplemente poniendo una llamada a getLoaderManager() en onCreate() . No es necesario llamar a los cargadores de inicio / reinicio allí.

Esto realmente me parece un error.

* Esta es la ruta del código incluso si no está utilizando fragmentos, así que no se confunda con eso.

Usando android-support-v4.jar y FragmentActivity (no hay fragmentos en este punto)

Tengo un AsyncTaskLoader que empiezo a cargar y luego cambio la orientación mientras el subproceso de fondo todavía se está ejecutando. En mis registros, veo que las respuestas llegan a las solicitudes de fondo. Las respuestas se completan y espero que se llame onLoadFinished (), pero nunca lo es.

Como medio de resolución de problemas, en el Manifiesto, si configuro android: configChanges = "orientación" enLoadFinished () se llama de la forma esperada.

Mi actividad implementa las devoluciones de llamada del cargador. En la fuente de LoaderManager.initLoader () veo que si el cargador ya existe, la nueva devolución de llamada se establece en la clase de objeto interno LoaderInfo pero no veo dónde se llama nuevamente a Loader.registerListener (). Parece que solo se llama a registerListener cuando se llama a LoaderManagerImpl.createAndInstallLoader ().

Sospecho que, dado que la actividad se destruye y se recrea en el cambio de orientación y como es el oyente de las devoluciones de llamada, la nueva actividad no está registrada para ser notificada.

¿Alguien puede confirmar mi comprensión y cuál es la solución para que se llame a onLoadFinished después del cambio de orientación?


Nikolay identificó el problema - Gracias.

Estaba llamando a initLoader fron onResume (). La documentación de Android establece:

"Normalmente, se inicializa un Loader dentro del método onCreate () de la actividad, o dentro del método onActivityCreated () del fragmento".

Lea "típicamente" como un poco más enfático que yo cuando se trata del ciclo de vida del cambio de configuración.

Moví mi llamada de initLoader a onCreate () y eso resolvió mi problema.

Creo que la razón es que en FragmentActivity.onCreate () se extrae una colección de LoaderManagers de LastNonConfigurationInstance y en FragmentActivity.onStart () hay algunos trabajos iniciales relacionados con Loaders y LoaderManagers. Las cosas ya están en proceso en el momento en que se llama onResume (). Cuando el cargador necesita ser instanciado por primera vez, llamar a initLoader desde fuera de onCreate () todavía funciona.