Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to close Cursor used in SimpleCursorAdapter

I'm using a SimpleCursorAdapter to display results in a ListView but since I've got to query my database lots of times during a search (using the SearchView widget) it worries me that the cursor might be left opened.

This is how I query my database and show the results in a ListView:

class SearchCustomers extends AsyncTask<String,Void,Cursor>{

        @Override
        protected Cursor doInBackground(String... params) {         
            //get the query
            String query=params[0].toLowerCase(Locale.getDefault());
            Cursor cursor=mDB.searchCustomersByName((query != null ? query : "@@@@"));
            return cursor;

        }

        @Override
        protected void onPostExecute(Cursor result) {           

            if (result != null) {

                String[] from = new String[] { QuickOrderDB.ID,
                        QuickOrderDB.NAME,
                        QuickOrderDB.ADDRESS,
                        QuickOrderDB.PHONE_NUMBER };

                int[] to = new int[] { R.id.customerIDTextView,
                        R.id.customerNameTextView,R.id.customerAddressTextView ,
                        R.id.customerPhoneTextView };

                SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(SearchCustomersActivity.this,
                        R.layout.results_customer_item, result, from, to);
                mResultsListView.setAdapter(cursorAdapter);                 

            }
        }           

    }   

I have tried many things to close the cursor, but even If I close it after mResultsListView.setAdapter(cursorAdapter); the result is always the same: an empty ListView.

I've already seen a couple of questions in which it is mentioned that the cursor will be closed automatically, but I want to make sure this is true.

Is there any official documentation about this? Does the SimpleCursorAdapter really close the cursor automatically??

Thanks in advance.

like image 387
Axel Avatar asked Sep 30 '14 20:09

Axel


2 Answers

  1. You need to close your cursor once you are done with it. Closing it after setAdapter() call would prevent the adapter from accessing the data. Hence a better place to close the cursor would be during current activities tear down life cycle stages such as onPause() or onStop(). (onDestroy() should not be used as Android run-time does not guarantee calling it. I think on latest version onStop() is guaranteed)
  2. I don't think SimpleCursorAdapter adapter automatically closes the cursor automatically. The official document mentions that changeCursor() automatically closes the old cursor, so another option could be to change your cursor after search. http://developer.android.com/reference/android/widget/CursorAdapter.html#changeCursor(android.database.Cursor)
like image 132
Gvancha Avatar answered Oct 07 '22 12:10

Gvancha


It's better if you get the Cursor using a CursorLoader instead of an AsyncTask. The Loaders are synched to the Activity/Fragment lifecycle via the LoaderManager, and the system will close the Cursor provided by the CursorLoader automatically for you when it's needed.

like image 42
GaRRaPeTa Avatar answered Oct 07 '22 13:10

GaRRaPeTa