ventajas phone kitkat desventajas cortas caracteristicas android android-asynctask android-loadermanager android-cursorloader

android - phone - ventajas y desventajas de ios



Android 3.0: ¿cuáles son las ventajas de usar las instancias de LoaderManager exactamente? (1)

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 muestra, para mostrar el resultado de una consulta del cursor que permite al usuario filtrar interactivamente el conjunto de resultados a través de un campo de entrada de consulta en la barra de acciones:

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 completo usted mismo con AsyncTask implicará 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.

También tenga en cuenta 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.

Esta es solo una API mucho más simple: no necesita saber nada acerca de 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 antiguas API de "cursor administrado" en Activity (que no funcionaba) t funciona tan bien como LoaderManager de todos modos).

(¡Por cierto, no olvides la nueva biblioteca estática de "soporte" que te permite usar la API completa de LoaderManager en versiones anteriores de Android hasta 1.6!)

Con 3.0 obtuvimos el lujoso LoaderManager , que maneja la carga de datos utilizando AsyncTaskLoader , CursorLoader y otras instancias personalizadas de Loader . Pero leyendo los documentos para estos, simplemente no pude entender el punto: ¿cómo es mejor que usar el viejo AsyncTask para la carga de datos?