Я создал этот вопрос здесь, так как не мог прокомментировать последний ответ (комментарии по какой-то причине отключены). Я думал, что открытие новой темы об этом только усложнит ситуацию.
Я получаю сбой приложения, когда перехожу с Действие A на Действие B и затем возвращаюсь к Действие A . Это не происходит все время - только иногда, и мне трудно найти ТОЧНО, где это происходит. Все происходит на одном устройстве (Nexus S), но я не верю, что это проблема устройства.
У меня есть несколько вопросов относительно ответа @Martin Stine.
- В документации говорится о
changeCursor(c);
: «Измените базовый курсор на новый курсор. Если он существует, он будет закрыт». Так почему я должен stopManagingCursor(currentCursor);
- не слишком ли избыточен ?
- Когда я использую код, предложенный @Martin Stine, я получаю исключение нулевого указателя. Причина этого заключается в том, что при первом «запуске» приложения
((SimpleCursorAdapter)getListAdapter())
будет иметь значение NULL, так как курсор еще не был создан. Конечно, я мог проверить, не получаю ли я нулевое значение, и только затем попытаться остановить управление курсором, но в конце концов я решил разместить свой `stopManagingCursor (currentCursor); в методе onPause () этого действия. Я думал, что таким образом у меня наверняка будет курсор, чтобы перестать управлять, и я должен сделать это непосредственно перед тем, как я оставлю Activity в другой. Проблема - я использую несколько курсоров (один для заполнения текста поля EditText, а другой для представления списка) в своей деятельности, я думаю, не все они связаны с курсором ListAdapter -
- Откуда мне знать, каким из них перестать управлять? Если у меня есть 3 вида списка?
- Должен ли я закрыть их все во время
onPause()
?
- Как получить список всех моих открытых курсоров?
Так много вопросов ... Надеюсь, кто-нибудь может помочь.
Когда я добираюсь до onPause()
, у меня есть курсор, чтобы прекратить управление, но мне еще предстоит определить, решает ли это проблему, поскольку эта ошибка появляется спорадически.
Большое спасибо!
ПОСЛЕ НЕКОТОРОГО ИССЛЕДОВАНИЯ:
Я нашел кое-что интересное, что могло бы дать ответ на «загадочную» сторону этого вопроса:
В задании A используются два курсора: один для заполнения поля EditText. Другой заключается в заполнении ListView.
При переходе от действия A к действию B и возвращении поле + ListView в действии A должно быть заполнено снова. Кажется, что поле EditText никогда не будет иметь проблемы с этим. Я не смог найти способ получить текущий курсор поля EditText (как в Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
), и причина говорит мне, что поле EditText не будет его хранить. С другой стороны, ListView будет «запоминать» свой курсор с прошлого раза (до Действия A -> Деятельность B). Кроме того, и это странно, Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
будет иметь другой идентификатор после Действия B -> Деятельность A и всего этого БЕЗ когда-либо я звоню
Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
stopManagingCursor(currentCursor);
Я полагаю, в некоторых случаях, когда системе необходимо освободить ресурсы, курсор будет убит, а когда действие B -> действие A, система все равно будет пытаться использовать этот старый мертвый курсор, что приведет к исключению. А в других случаях система создаст новый курсор, который еще жив, и, таким образом, исключение не произойдет. Это может объяснить, почему это появляется только иногда. Я предполагаю, что это трудно отладить из-за разницы в скорости приложения при запуске или отладке приложения. При отладке это занимает больше времени и, таким образом, может дать системе время для создания нового курсора или наоборот.
В моем понимании это делает использование
Cursor currentCursor = ((SimpleCursorAdapter)currentListAdapter).getCursor();
stopManagingCursor(currentCursor);
В соответствии с рекомендациями @Martin Stine должен в НЕКОТОРЫХ случаях и избыточный в ДРУГИХ: если я возвращаюсь к методу, и система пытается использовать мертвый курсор, необходимосоздайте новый курсор и замените его в ListAdapter, в противном случае я получаю злые пользователи приложения из-за сбоя приложения.В другом случае, когда система найдет себе новый курсор - вышеприведенные строки излишни, поскольку они лишают законной силы хороший курсор и создают новый.
Я думаю, что для предотвращения этой избыточности мне понадобится что-то вроде этого:
ListAdapter currentListAdapter = getListAdapter();
Cursor currentCursor = null;
Cursor c = null;
//prevent Exception in case the ListAdapter doesn't exist yet
if(currentListAdapter != null)
{
currentCursor = ((SimpleCursorAdapter)currentListAdapter).getCursor();
//make sure cursor is really dead to prevent redundancy
if(currentCursor != null)
{
stopManagingCursor(currentCursor);
c = db.fetchItems(selectedDate);
((SimpleCursorAdapter)getListAdapter()).changeCursor(c);
}
else
{
c = db.fetchItems(selectedDate);
}
}
else
{
c = db.fetchItems(selectedDate);
}
startManagingCursor(c);
Мне бы очень хотелось услышать, что вы об этом думаете!