Android 3.0 – Quels sont les avantages de l'utilisation des instances LoaderManager exactement?

Avec 3.0, nous avons eu le LoaderManager chic, qui gère le chargement des données en utilisant AsyncTaskLoader , le CursorLoader et d'autres instances Loader personnalisées. Mais en lisant les docs pour ces derniers, je ne pouvais pas comprendre: comment sont-ils meilleurs que d'utiliser le bon vieux AsyncTask pour le chargement de données?

  • La méthode Android getOrientation () renvoie de mauvais résultats
  • Vues de recyclage en vue de défilement
  • L'application Android Proguard pour LVL et Fragment Compatability Support
  • Android HttpUrlConnection: Post Multipart
  • L'animation TextInputLayout chevauche le texte lorsque le texte est défini par programme
  • Comment utiliser le flux Master / Detail avec les onglets sur Android
  • Comment éviter les poids imbriqués?
  • Existe-t-il un moyen d'obtenir une sortie de débogage copie-et-pastable dans l'Emulateur SDK Android?
  • Android: ImageView réduit l'image source
  • UNREGISTERED_ON_API_CONSOLE tout en obtenant le jeton OAuth2 sur Android
  • L'android JVM peut-il fonctionner sur un PC aussi?
  • Trouver la distance entre deux points sur la carte à l'aide de Google Map API V2
  • One Solution collect form web for “Android 3.0 – Quels sont les avantages de l'utilisation des instances LoaderManager exactement?”

    Eh bien, ils sont beaucoup plus simples à mettre en œuvre, et s'occuper de tout sur la gestion du cycle de vie, de sorte que beaucoup moins susceptibles d'erreurs.

    Il suffit de regarder l'exemple de code pour afficher le résultat d'une requête de curseur qui permet à l'utilisateur de filtrer de façon interactive le résultat à travers un champ de saisie de requête dans la barre d'action:

     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); } } 

    La mise en œuvre correcte de cet exemple complet vous-même avec AsyncTask impliquera beaucoup plus de code … et même alors, allez-vous mettre en œuvre quelque chose d'aussi complet et efficace? Par exemple, votre implémentation conservera-t-elle le Cursor chargé dans les changements de configuration de l'activité afin qu'il ne soit pas nécessaire de le re-interrogé lorsque les nouvelles instances sont créées? LoaderManager / Loader le fera automatiquement pour vous, tout en prenant soin de créer et de fermer correctement le Cursor en fonction du cycle de vie de l'activité.

    Notez également que l'utilisation de ce code ne requiert pas que vous réfléchissiez à ce que le travail long soit exécuté sur le thread UI principal. LoaderManager et CursorLoader prennent soin de tout cela pour vous, en vous assurant que vous ne bloquerez jamais le thread principal en interagissant avec le curseur. Pour ce faire correctement, vous devez avoir deux objets Cursor actifs en même temps en points, afin que vous puissiez continuer à afficher une interface utilisateur interactive avec votre Cursor actuel tandis que le prochain à afficher est en cours de chargement. LoaderManager fait tout cela pour vous.

    Il s'agit simplement d'une API beaucoup plus simple: il n'est pas nécessaire de connaître AsyncTask et de réfléchir à ce qu'il faut exécuter en arrière-plan, pas besoin de penser au cycle de vie de l'activité ni à utiliser les anciennes API du «curseur géré» dans Activité (qui n'a pas été " T Work ainsi que LoaderManager de toute façon).

    (Btw n'oubliez pas la nouvelle bibliothèque statique "support" qui vous permet d'utiliser l'API LoaderManager complète sur les anciennes versions d'Android jusqu'à 1.6!)

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.