I created this question here since I could not comment on the last answer (for some reason, comments are disabled). I thought that opening a new thread on this would only complicate the situation.
I get application crashes when I switch from Activity A to Activity B and then return to Activity A. This does not always happen — only occasionally, and it’s hard for me to find EXACTLY where this happens. Everything happens on one device (Nexus S), but I do not think that this is a problem with the device.
I have a few questions regarding @Martin Stine's answer.
- The documentation says
changeCursor(c); : "Change the base cursor to a new cursor. If there is an existing cursor, it will be closed." So why should I stopManagingCursor(currentCursor); - not redundant ? - When I use the code suggested by @Martin Stine, I get a null pointer exception. The reason for this is that the first "start" of the application
((SimpleCursorAdapter)getListAdapter()) will evaluate to NULL, because no pointer has yet been created. Of course, I could check if I get null and only then try to stop the cursor control, but finally I decided to place my `stopManagingCursor (currentCursor); in the onPause () method of this activity. I thought that I would surely have a pointer to stop control, and I must do this before I leave the action to others. Problem - I use several cursors (one to fill the text of the EditText field, and the other to represent the list) in my activity, I think not all of them are associated with the ListAdapter cursor -- How to find out which one to stop? If I have 3 different kinds of list?
- Should I close them during
onPause() ? - How do I get a list of all my open cursors?
So many questions ... Hope someone can help.
When I get to onPause() , I have a pointer to stop the control, but I have not yet decided if this solves the problem, as this error appears sporadically.
Thank you very much!
AFTER SOME RESEARCHES:
I found something interesting that could provide an answer to the "mysterious" side of this problem:
Step A uses two cursors: one to populate the EditText field. Another is to populate a ListView.
When moving from Activity A to Activity B and returning, the + ListView field in Activity A should be filled again. It seems that there will never be a problem with this in the EditText field. I could not find a way to get the current EditText cursor (for example, in Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor(); ), and the reason tells me that the EditText field will not save it. On the other hand, the ListView will “remember” its cursor from the last time (from Activity A → Activity B). In addition, and this is strange, Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor(); there will be a different identifier after Activity B → Activity A and all this WITHOUT ever calling
Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor(); stopManagingCursor(currentCursor);
I think in some cases when the system needs to free resources, the cursor will be killed, and when Activity B → Activity A, the system will still try to use this old dead cursor, which will lead to an exception. And in other cases, the system will come up with a new cursor that is still alive, and thus an exception will not occur. This may explain why this only appears occasionally. I think this is difficult to debug due to the difference in application speed when starting or debugging the application. Debugging requires more time and, therefore, can give the system time a new cursor or vice versa.
In my understanding, it makes use of
Cursor currentCursor = ((SimpleCursorAdapter)currentListAdapter).getCursor(); stopManagingCursor(currentCursor);
As recommended by @Martin Stine a, it should in some cases be redundant in OTHERS: if I return to the method and the system tries to use the dead cursor, I need to create a new cursor and replace it with a ListAdapter, otherwise I get angry application users with a broken application. In another case, when the system finds a new cursor for itself, the lines above are redundant, because they invalidate a good cursor and create a new one.
I assume that to prevent this redundancy, I will need something like this:
ListAdapter currentListAdapter = getListAdapter(); Cursor currentCursor = null; Cursor c = null;
I would love to hear what you think about it!