Загрузчики и onLoaderReset Android

Я реализовал загрузчик в своем приложении для запроса данных из базы данных. Я слушаю происходящие изменения, внедряя LoaderCallbacks<Cursor> listener. Проблема, с которой я сталкиваюсь, заключается в использовании метода onLoaderReset(Loader<Cursor> loader), когда мои данные меняются, и я хочу аннулировать и освободить любые данные, связанные с загрузчиком. Во всех примерах в этом методе есть следующий вызов:

mAdapter.swapCursor(null);

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

(например, непосредственно из возвращенного курсора в onLoadFinished(Loader<Cursor> loader, Cursor data))

        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

            if (data.moveToFirst()) {
                TOTAL_CARDS = data.getCount();
                mView.createCards(TOTAL_CARDS);
            } else {
                TOTAL_CARDS = 0;
                mView.createCards(TOTAL_CARDS);
            }


        }

Что здесь было бы уместно сделать, похожее на mAdapter.swapCursor. У меня нет большого опыта работы с загрузчиками, на самом деле я только начал с ними работать, поэтому, если у кого-то есть решение этой проблемы, я был бы признателен. Спасибо!

РЕДАКТИРОВАТЬ: На данный момент я передаю null загрузчику, и он работает следующим образом:

@Override
public void onLoaderReset(Loader<Cursor> loader) {
        loader = null;
}

};

Но правильное ли это решение?


person Sandra    schedule 17.10.2012    source источник


Ответы (1)


Делает

@Override
public void onLoaderReset(Loader<Cursor> loader) {
  loader = null;
}

так же хорошо, как ничего не делать. В вашем примере кода вы просто обнуляете локальную ссылку вашего метода на его аргумент. Однако эта ссылка всегда будет удаляться после возврата вызова метода. (Возможно, вы захотите прочитать Является ли Java передачей по ссылке или передачей по значению? для дальнейшего обсуждения темы.)

Метод onLoaderReset(Loader) вызывается, когда обратный вызов вашего загрузчика (обычно экземпляр Activity или Fragment) получает запрос на освобождение всех ссылок на Cursor, которые он получил ранее через onLoadFinished(Loader, Cursor). По сути, этот метод требует очистки, так как Loader скоро закроет Cursor, который он предоставил вам ранее. После того, как курсор был закрыт, вы больше не сможете получать данные по нему. Однако, если курсор все еще будет использоваться (обычно CursorAdapter, как вы упомянули) после его закрытия, это вызовет исключение.

Точно так же onLoadFinished(Loader, Cursor) имеет неявный контракт, требующий, чтобы после возврата метода любые ранее предоставленные объекты Cursor больше не использовались. Вместо этого вы должны заменить эти ссылки новым курсором, который предоставляется в качестве аргумента метода. Напротив, onLoaderReset(Loader) просит вас выполнить тот же контракт, но без предоставления замены, т. е. вы должны удалить все ссылки на ранее полученный Cursor.

В вашем примере вы не позволяете своему Cursor выйти из области действия метода, но вместо этого вы сразу читаете данные. Следовательно, нет необходимости удалять какие-либо ссылки на объект Cursor, предоставленный через onLoadFinished(Loader, Cursor), поскольку их нет. Таким образом, пустая реализация onLoaderReset(Loader) для выполнения контракта интерфейса сделает эту работу за вас.

person Rafael Winterhalter    schedule 02.05.2013
comment
Спасибо за ваш ответ и объяснение. Просто быстрый вопрос, хотя. Если бы у меня была ссылка на Cursor в onLoadFinished (которую я бы использовал вне области действия метода), то я должен закрыть ее в onLoaderReset, верно? - person Sandra; 07.05.2013
comment
Вообще-то, нет. Загрузчик закроет для вас ссылку Cursor. Это основная причина, по которой вы должны выпускать ссылки. Скорее всего, вы не сможете использовать старый курсор после возврата методов onLoadFinished(Loader, Cursor)/onLoaderReset(Loader). - person Rafael Winterhalter; 07.05.2013
comment
Итак, каков хороший пример использования метода onLoaderReset()? - person IgorGanapolsky; 19.08.2014
comment
Метод представляет собой крючок жизненного цикла. Обычно этот метод используется для изменения состояния включающего экземпляра или экземпляра Loader. - person Rafael Winterhalter; 19.08.2014