Detailed explanation and examples of Android onLoadFinished and onLoaderReset callbacks
onLoadFinished
This method is called after the previously created loader has completed its loading process. This method is guaranteed to be called before the data applied to the loader is released. In this method, you have to delete all usage of the old data (as it will be deleted soon), but don't free them yourself, because their loader will do these things.
Once the loader learns that the application no longer uses the data, it will release the data immediately. For example, if the data is a cursor from the CursorLoader, you should not call the cursor close(), and if the cursor is placed in a CursorAdapter, you should use the swapCursor() method to prevent the old cursor from being closed. For example:
//This Adapter is used to display the data of the list.SimpleCursorAdapter mAdapter; ... 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.) (data); }
onLoaderReset
This method is called when a created loader is reset so that its data is invalid. This callback allows you to discover when the data will be released so you can release a reference to it.
The following implementation calls swapCursor() with null parameter:
// This Adapter is used to display the data of the listSimpleCursorAdapter mAdapter; ... public void onLoaderReset(Loader<Cursor> loader) { //Here is the cursor used for the above onLoadFinished() will be executed when it is closed, we need to make sure we no longer use it (null); }
example
As an example, a Fragment displays the contents of a ListView that returns query data from the contact contentprovider. It uses a CursorLoader to manage queries to the provider.
public static class CursorLoaderListFragment extends ListFragment implements OnQueryTextListener, <Cursor> { // This is the Adapter for displaying list data SimpleCursorAdapter mAdapter; // If not null, this is the current search oversight String mCurFilter; @Override public void onActivityCreated(Bundle savedInstanceState) { (savedInstanceState); // If there is no data in the list, give the control some text to display. In a real application // Get this application resource. setEmptyText("No phone numbers"); // We have a menu item in the action bar. setHasOptionsMenu(true); // Create an empty adapter, we will use it to display the loaded data mAdapter = new SimpleCursorAdapter(getActivity(), .simple_list_item_2, null, new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, new int[] { .text1, .text2 }, 0); setListAdapter(mAdapter); // Prepare loader. Maybe reconnect to 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 = ("Search"); (.ic_menu_search); (MenuItem.SHOW_AS_ACTION_IF_ROOM); SearchView sv = new SearchView(getActivity()); (this); (sv); } public boolean onQueryTextChange(String newText) { // Called when the search string on the action bar changes. renew //Search the filter and restart the loader to execute a new query mCurFilter = !(newText) ? newText : null; getLoaderManager().restartLoader(0, null, this); return true; } @Override public boolean onQueryTextSubmit(String query) { // We don't care about this method return true; } @Override public void onListItemClick(ListView l, View v, int position, long id) { // Write the code you want to write ("FragmentComplexList", "Item clicked: " + id); } // This is the data from a row of contacts we want to obtain. 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) { // Called when a new loader needs to be created. There is only one Loader in this case. //So we don’t need to care about ID. First set the base URI, which points to the contact person Uri baseUri; if (mCurFilter != null) { baseUri = (Contacts.CONTENT_FILTER_URI, (mCurFilter)); } else { baseUri = Contacts.CONTENT_URI; } // Now create and return a CursorLoader, which will be responsible for creating a // Cursor is used to display data 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 care about the closing of the old cursor when we return) (data); } public void onLoaderReset(Loader<Cursor> loader) { //Before the last Cursor is ready to enter the above onLoadFinished(). // Cursor is going to be closed, we need to make sure it is no longer used. (null); } }
Thank you for reading, I hope it can help you. Thank you for your support for this site!