Ho creato questa domanda qui come non ho potuto commentare l'ultima risposta (commenti disabili per qualche motivo). Pensavo che aprire una nuova discussione su questo avrebbe solo complicato le cose.
ottengo crash dell'applicazione quando vado da Activity Un a attività B e poi tornare a Attività A. Questo non succede sempre - solo qualche volta e sto avendo difficoltà a trovare ESATTAMENTE dove ciò accade. Tutto accade sullo stesso dispositivo (Nexus S) ma non credo che questo sia un problema del dispositivo.
Ho alcune domande riguardanti la risposta di @Martin Stine.
- Nella documentazione che dice di
changeCursor(c);
: "Cambia il cursore sottostante ad un nuovo cursore Se c'è un cursore esistente sarà chiuso.". Quindi, perché devo stopManagingCursor(currentCursor);
- non è ridondante?
- Quando uso il codice offerto da @Martin Stine ottengo un'eccezione di puntatore nullo. Il motivo è che nella prima "esecuzione" dell'applicazione
((SimpleCursorAdapter)getListAdapter())
verrà valutata NULL perché non è stato ancora creato alcun cursore.Certo ho potuto verificare se non ottengo un nullo e solo allora provare ad arrestare per gestire il cursore ma alla fine ho deciso di mettere la mia `stopManagingCursor (currentCursor); nel metodo onPause() di questa attività. Ho pensato che in questo modo avrò sicuramente un cursore per smettere di gestire e dovrei farlo appena prima di lasciare l'attività su un'altra. Il problema - sto usando diversi cursori (uno per riempire un testo di un campo EditText e l'altro per una visualizzazione elenco) nella mia attività io non immagino tutti loro sono legati a un cursore ListAdapter -
- Come faccio sapere quale smettere di gestire? Se ho 3 diverse visualizzazioni di lista?
- Dovrei chiudere tutti loro durante
onPause()
?
- Come ottengo una lista di tutti i miei cursori aperti?
Tante domande ... La speranza che qualcuno potesse aiutare.
Quando arrivo a onPause()
ho un cursore per interrompere la gestione ma devo ancora determinare se questo risolve il problema in quanto questo errore si presenta sporadicamente.
Grazie mille!
Dopo alcune indagini:
ho trovato qualcosa di interessante che potrebbe dare la risposta al lato "misterioso" di questo numero:
Attività A utilizza due cursori: uno di riempire un EditText campo. L'altro è popolare un ListView.
Quando si passa da Activity A alla attività B e tornando, il campo + ListView in attività A deve essere riempito di nuovo. Sembra che il campo EditText non abbia mai un problema con quello. Non ho trovato un modo per ottenere il cursore corrente del campo EditText (come in Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
) e la ragione mi dice che il campo EditText non lo manterrà. D'altra parte il ListView "ricorderà" il suo cursore dall'ultima volta (da prima dell'attività A -> Attività B). Inoltre, e questa è la cosa strana, il Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
avrà un ID diverso dopo l'attività B -> Attività A e tutto questo SENZA me mai chiamare
Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
stopManagingCursor(currentCursor);
Credo che in alcuni casi, quando le esigenze del sistema per liberare risorse, il cursore verrà ucciso e quando Attività B -> Attività A, il sistema tenterà comunque di utilizzare questo vecchio cursore morto, che genererà un'eccezione. E in altri casi il sistema visualizzerà un nuovo cursore che è ancora vivo e quindi non si verificherà alcuna eccezione. Questo potrebbe spiegare perché questo si presenta solo a volte. Immagino che sia difficile eseguire il debug a causa della differenza di velocità dell'applicazione durante l'esecuzione o il debug dell'applicazione. Durante il debug, ci vuole più tempo e quindi potrebbe dare al sistema il tempo di creare un nuovo cursore o viceversa.
Nella mia comprensione questo rende l'utilizzo di
Cursor currentCursor = ((SimpleCursorAdapter)currentListAdapter).getCursor();
stopManagingCursor(currentCursor);
Come raccomandato dal @ Martin Stine un must in alcuni casi e ridondante negli altri: se torno al metodo e il sistema sta cercando per utilizzare un cursore morto, è necessario creare un nuovo cursore e sostituirlo in ListAdapter, altrimenti mi arrabbio con gli utenti dell'app con un'app bloccata.In un altro caso quando il sistema si troverà un nuovo cursore - le linee sopra sono ridondanti in quanto invalideranno un buon cursore e ne creeranno uno nuovo.
immagino per evitare questa ridondanza avrei bisogno di qualcosa di simile:
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);
Mi piacerebbe sentire cosa ne pensate di questo!
State di mira specificamente a nido d'ape. Ho appena scoperto che la mia app Eclair + è stata interrotta in Honeycomb, a causa di startManagingCursor(). La mia app è destinata ai telefoni, ma non aspetta i clienti arrabbiati quando esce Ice Cream Sandwich. – Tenfour04
Sì, sono specificamente mirato al favo (compresse). –
@ cyber-monaco Ciao - Sto avendo un problema. Non riesco ad implementarlo perché il mio codice non riconosce CursorLoader. L'ho importato correttamente ma non riconosce l'importazione. Come posso risolvere questo? – Mxyk