Когда закрыть курсор, используемый в SimpleCursorAdapter

Я использую SimpleCursorAdapter для отображения результатов в ListView, но так как я много раз запрашивал свою базу данных во время поиска (используя виджет SearchView), меня беспокоит, что курсор может быть оставлен открытым.

Вот как я запрашиваю свою базу данных и показываю результаты в 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);                 

            }
        }           

    }   

Я пробовал много вещей, чтобы закрыть курсор, но даже если я закрою его после mResultsListView.setAdapter(cursorAdapter);, результат всегда будет таким же: пустой ListView.

Я уже видел пару вопросов, в которых упоминается, что курсор будет закрыт автоматически, но я хочу убедиться, что это правда.

Есть ли официальная документация об этом? Действительно ли SimpleCursorAdapter автоматически закрывает курсор??

Спасибо заранее.

Ответ 1

  • Вам нужно закрыть курсор, как только вы закончите с ним. Закрытие его после вызова setAdapter() будет препятствовать доступу адаптера к данным. Следовательно, лучшим местом для закрытия курсора было бы во время текущих действий срывать этапы жизненного цикла, такие как onPause() или onStop(). (onDestroy() не следует использовать, поскольку время выполнения Android не гарантирует его вызова. Я думаю, что в последней версии onStop() гарантировано)
  • Я не думаю, что адаптер SimpleCursorAdapter автоматически автоматически закрывает курсор. В официальном документе упоминается, что changeCursor() автоматически закрывает старый курсор, поэтому другой вариант может заключаться в изменении курсора после поиска. http://developer.android.com/reference/android/widget/CursorAdapter.html#changeCursor(android.database.Cursor)

Ответ 2

Лучше, если вы используете курсор с помощью CursorLoader вместо AsyncTask. Погрузчики синхронизируются с жизненным циклом Activity/Fragment через LoaderManager, и система автоматически закрывает курсор, предоставленный CursorLoader, когда вам нужно.

Ответ 3

Вы должны закрыть курсор в своем обратном вызове фрагмента или активности onPause(). После того, как действие приостановлено, возможно, что более старые системы Android будут удалять приложение в свободной памяти.

Это означает, что вам нужно восстановить курсор в соответствующем обратном вызове onResume().