问题
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.
回答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)
- 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)
回答2:
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.
回答3:
You should close the cursor in your fragment or activity's onPause()
callback. After the activity is paused it's possible that older Android systems will delete the app to free memory.
This implies that you need to reestablish the cursor in the corresponding onResume()
callback.
回答4:
Don't create a variable for the cursor, just add the db query directly into the constructor as the argument c
, db.query()
or a method that holds the desired query), this seems to work.
SimpleCursorAdapter (Context context,
int layout,
Cursor c,
String[] from,
int[] to,
int flags)
来源:https://stackoverflow.com/questions/26129109/when-to-close-cursor-used-in-simplecursoradapter