Con 3.0 que tiene la fantasía LoaderManager
, que se ocupa de la carga de datos utilizando la AsyncTaskLoader
, la CursorLoader
, y otros casos de encargo Loader
. Pero leyendo los documentos para estos, simplemente no pude entender el punto: ¿cómo son estos mejores que solo usar el viejo AsyncTask
para cargar datos?Android 3.0: ¿cuáles son las ventajas de utilizar las instancias de LoaderManager exactamente?
Respuesta
Bueno, son mucho más simples de implementar y se ocupan de todo lo relacionado con la administración del ciclo de vida, por lo que son mucho menos propensos a errores.
Basta con mirar el código de ejemplo, para mostrar el resultado de una consulta de cursor que permite al usuario de forma interactiva a filtrar el conjunto de resultados a través de un campo de entrada de consulta en la barra de acción:
public static class CursorLoaderListFragment extends ListFragment
implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {
// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;
// If non-null, this is the current filter the user has provided.
String mCurFilter;
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText("No phone numbers");
// We have a menu item to show in action bar.
setHasOptionsMenu(true);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_2, null,
new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
new int[] { android.R.id.text1, android.R.id.text2 }, 0);
setListAdapter(mAdapter);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Place an action bar item for searching.
MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView sv = new SearchView(getActivity());
sv.setOnQueryTextListener(this);
item.setActionView(sv);
}
public boolean onQueryTextChange(String newText) {
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
getLoaderManager().restartLoader(0, null, this);
return true;
}
@Override public boolean onQueryTextSubmit(String query) {
// Don't care about this.
return true;
}
@Override public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("FragmentComplexList", "Item clicked: " + id);
}
// These are the Contacts rows that we will retrieve.
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
Contacts._ID,
Contacts.DISPLAY_NAME,
Contacts.CONTACT_STATUS,
Contacts.CONTACT_PRESENCE,
Contacts.PHOTO_ID,
Contacts.LOOKUP_KEY,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = Contacts.CONTENT_URI;
}
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ Contacts.DISPLAY_NAME + " != ''))";
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
}
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
}
implementar correctamente este ejemplo completa usted mismo con AsyncTask va a involucrar mucho más código ... y aun así, ¿va a implementar algo tan completo y funcionando bien? Por ejemplo, ¿conservará su implementación el Cursor cargado en todos los cambios de configuración de actividad para que no sea necesario volver a consultar cuando se creen las nuevas instancias? LoaderManager/Loader lo hará automáticamente por usted, y se encargará de crear y cerrar correctamente el Cursor en función del ciclo de vida de la actividad.
Observe también que el uso de este código no requiere que piense en absoluto para asegurarse de que el trabajo prolongado se realice fuera de la secuencia de interfaz de usuario principal. LoaderManager y CursorLoader se encargan de todo eso por usted, asegurándose de que nunca bloqueará el hilo principal mientras interactúa con el cursor. Para hacer esto correctamente, en realidad necesitas tener dos objetos del Cursor activos al mismo tiempo en los puntos, para que puedas continuar mostrando una IU interactiva con tu Cursor actual mientras se carga el siguiente para mostrar. LoaderManager hace todo eso por ti.
Esto es solo una API mucho más simple: no necesita saber sobre AsyncTask y pensar qué necesita ejecutarse en segundo plano, sin necesidad de pensar en el ciclo de vida de la actividad o cómo usar las viejas API de "cursor administrado" en Activity (que no funcionó tan bien como LoaderManager de todos modos).
(Por cierto no se olvide de la nueva "apoyo" biblioteca estática que le permiten utilizar la API LoaderManager completa en versiones anteriores de Android a un 1,6!)
¡Excelente respuesta! Sí, todavía era demasiado fácil para los principiantes hacer un uso incorrecto de AsyncTask: no podía manejar fácilmente los cambios de configuración y tenías que tener cuidado si necesitabas algo con un contexto en 'onProgressUpdate', etc. para asegurarte de que no causaba pérdidas de memoria. . –
Tal vez soy yo, ¡pero esto no parece fácil! – Ants
@hackbod He intentado tanto con Android 4.0 como con la biblioteca de soporte, y parece que el cursor _no se conserva_ en los cambios de configuración. Incluso encontré un error relacionado en esto: http://code.google.com/p/android/issues/detail?id=25112 – inazaruk
- 1. ¿Cuáles son las ventajas de utilizar Rubinius
- 2. ¿Cuáles son las ventajas de utilizar POCO en DataTables?
- 3. ¿Cuáles son las ventajas de usar Automapper?
- 4. ¿Cuáles son las ventajas reales de las colecciones inmutables?
- 5. ¿Cuáles son las ventajas de Lazy Evaluation?
- 6. ¿Cuáles son las ventajas de Perforce?
- 7. ¿Cuáles son las ventajas de usar Qt?
- 8. Cuáles son las ventajas de VistaDB
- 9. ¿Cuáles son las ventajas exactas de los Fragmentos en Android 3.0?
- 10. ¿Cuáles son las ventajas de las macros de esquema?
- 11. ¿Cuáles son las ventajas prácticas del currying?
- 12. ¿Cuáles son las ventajas de utilizar las bibliotecas de C++ Boost?
- 13. ¿Cuáles son las ventajas de agregar instancias de delegado a Component.Events (EventHandlerList)?
- 14. node.js - cuáles son las ventajas de usar jade
- 15. ¿Qué es NSZone? ¿Cuáles son las ventajas de usar initWithZone :?
- 16. ¿Cuáles son las ventajas y desventajas de usar boost :: iterator_facade?
- 17. ¿Cuáles son las ventajas/desventajas de usar Maven?
- 18. ¿Cuáles son las ventajas de Blocking Queue en Java?
- 19. ¿Cuáles son las ventajas y desventajas de usar esquemas XML?
- 20. ¿Cuáles son las ventajas de usar un errback?
- 21. ¿Cuáles son las ventajas de cargar DLL de forma dinámica?
- 22. ¿Cuáles son las ventajas de un procesador de 64 bits?
- 23. Postgresql enum ¿Cuáles son las ventajas y desventajas?
- 24. ¿Cuáles son las ventajas del uso de Node.js vs PHP
- 25. Cuáles son las ventajas de MVC3 sobre MVC2
- 26. ¿Cuáles son las ventajas de LePUS3 sobre UML?
- 27. Cuáles son las ventajas de C# sobre Python
- 28. ¿Cuáles son las 'grandes' ventajas de tener Poco con ORM?
- 29. ¿Cuáles son las ventajas de git over git-svn?
- 30. ¿Cuáles son las ventajas de usar Ruby NArray sobre Array?
Salida [** ** este post] (http : //www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html) ... la primera parte enumera las ventajas de usar 'LoaderManager' sobre el' 'startManagingCursor'' obsoleto ... – user1422551
[** Entender el 'LoaderManager' **] (http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html) es una gran publicación para aprender. –