2011-09-29 16 views
6

Per implementare l'accesso al database nella mia applicazione ho seguito Lars Vogel tutorial, ma io sono molto confuso su un paio di cose ...a qualche domanda sulla cursori database SQLite in Android

1) Ogni volta che una chiamata è fatto a fetchTodo verrà creato e restituito un nuovo cursore. Lasciando il cursore precedente per il garbage collector. Quindi, se non uso startManagingCursor o anche lo CursorLoader per quella materia, dovrei chiamare un .close() sul cursore quando ho finito con esso? Al di fuori di fetchTodo portata del corso, ad esempio:

Cursor cursor = mNotesAdapter.fetchTodo(); 
// do something... 
cursor.close(); 

ho finito con questo cursore e nuovo verrà creato sul prossimo recuperare, devo chiudere in questo modo, allora o dovrei lasciare per il garbage collector ? Anche se penso che sto parlando di 2 cose completamente diverse ... L'essere punto, dovrei chiuderlo come nell'esempio sopra o no?

2)Cursor ha anche un metodo .deactivate() e la documentazione dice che utilizza meno risorse (di cursori attivi). Quando esattamente dovrei usare questo? Ad esempio, nella mia app, ho uno ListActivity che viene popolato attraverso un SimpleCursorAdapter (l'inizializzazione del codice per questo viene chiamata solo una volta). Il cursore utilizzato è una variabile membro della classe, perché ne ho bisogno al di fuori del metodo che popola la lista. Ho bisogno di requery il database quando qualcosa viene cancellato da esso. Ma fino a quando non viene cancellato un record, che è un'azione dell'utente e potrebbe volerci un po 'di tempo, dovrei disattivare il cursore nel frattempo? Perché sarà di nuovo attivo quando chiamo di nuovo .requery(). O il SimpleCursorAdapter sta per smettere di funzionare perché il cursore non è attivo?

EDIT: Ho appena provato questo e ho scoperto che non posso chiamare deactivate() dopo aver impostato l'adattatore del cursore. L'elenco sarà vuoto se il cursore non è attivo, quindi è necessario rimanere attivo fino a quando viene visualizzato ListActivity. Alla fine, dovremmo semplicemente lasciarlo gestire da StartManagingCursor. O il nuovo CursorLoader.

3) So che startManagingCursor/stopManagingCursor sono deprecati, ma io non sto mira a nido d'ape (almeno per il momento) e non voglio a che fare con il nuovo CursorLoader per ora. Ma nel tutorial sopra, startManagingCursor viene utilizzato ovunque, ma stopManagingCursor non viene mai chiamato una volta. Perchè no? Android se ne occupa a suo modo? Qualsiasi situazione dovrei chiamare stopManagingCursor?

risposta

9

Modifica: Aggiornato risposta a riflettere domanda aggiornato 1:

1) Ogni volta che viene effettuata una chiamata a fetchTodo un nuovo cursore verrà creato e restituito. Lasciando il cursore precedente per il garbage collector. Quindi, se non utilizzo startManagingCursor o anche il CursorLoader per che importa, dovrei chiamare un .close() sul cursore quando ho finito con esso?

Sì, si dovrebbe assolutamente né dire Android per startManagingCursor(), utilizzare LoaderManager/CursorLoader o close() da soli. In caso contrario si verificherà una perdita di memoria, il GC non sarà di aiuto in quanto vi sono le risorse native dietro lo Cursor (ad esempio, gli handle di file nel database).

2) Il cursore ha anche un metodo .deactive() e la documentazione dice che utilizza meno risorse (di cursori attivi). Quando esattamente dovrei usare questo? ...

EDIT ad altri lettori: Il PO ha trovato una risposta e postato nella sua interrogazione. Ciò che segue ancora vale:

Non ho mai usato deactivate() (non c'è deactive()), forse qualcun altro può spiegarlo. Se si desiderano richieste/aggiornamenti davvero indolori, consultare il framework LoaderManager - non solo per Honeycomb: utilizzando la libreria compat è possibile utilizzare LoaderManager (e Fragments) fino ad Android 1.6. Non solo è meno codice per te da scrivere, ma scarica completamente queste cose su Android, molto più di startManagingCursor().

EDIT2: Alcune note sul LoaderManager

Ci sono LoaderManager tutorial su developer.android.com ma questi sono abbastanza ... complessa e difficile da comprendere per la prima volta come la maggior parte dei tutorial lì. Ho anche dovuto scavare molto, la migliore soluzione all-in-one che ho trovato finora è http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/ (più tutte le sorgenti javadocs e compat lib che puoi trovare) --- il modo in cui lo LoaderManager funziona è molto simile al (ora anche deprecato, sostituito da DialogFragment) finestre di dialogo gestite con i loro metodi onCreateDialog, onPrepareDialog in cui basta dire a Android di "mostrare la finestra di dialogo # 123" e quindi Android chiama il tuo codice con tale ID; lo stesso per caricatori: "carica caricatore # 123", chiamate Android su onCreateLoader().

L'unico inconveniente ovvio è inizialmente, che LoaderManager fa molto affidamento sul framework ContentProvider e alcune persone sembrano non apprezzarlo. Certo, è un ulteriore apprendimento e codice, ma una volta che hai uno ContentProvider per i tuoi dati (anche se usato solo in privato nella tua app), tutti i bindng dati-to-view è un gioco da ragazzi con CursorLoader. IMHO, c'è poca differenza tra posizionare il proprio "fornitore di contenuti" ed effettivamente attuare il ContentProvider - ma questo è solo il mio parere molto controversa :)

3) So che startManagingCursor/stopManagingCursor sono deprecati ma io' m non mirato a nido d'ape (almeno per il momento) e io non voglio occuparmi del nuovo CursorLoader per ora. Tuttavia, nell'esercitazione precedente, startManagingCursor viene utilizzato ovunque, ma stopManagingCursor non viene mai chiamato una volta. Perchè no? Android occupa con quello a modo suo? Qualsiasi situazione dovrei chiamare stopManagingCursor?

Una volta che si chiama startManagingCursor() il Cursor non è più il tuo problema. Android si prenderà cura di chiudere il cursore quando il tuo Activity viene distrutto (l'utente si allontana, il cambio di orientamento, ...). Non è necessario abbinare una chiamata a con una chiamata a stopManagingCursor() - di solito non si vuole assumersi l'onere di gestire uno Cursor di nuovo una volta che ci si è sbarazzati di esso.

+0

# 1 Ho completamente interpretato erroneamente i miei pensieri su quella domanda, ho bisogno di riformularlo ... # 2 Sì, intendevo "disattivare" (errore). Non riesco davvero a trovare una buona documentazione su come usare il 'LoaderManager', nemmeno qui nelle domande SO.# 3 Capisco il punto, ma se non dovrei usare 'stopManagingCursor' se ho fatto una chiamata a' startManagingCursor', perché questo metodo esiste anche in primo luogo? –

+0

Ho appena riscritto l'intera domanda # 1 @philipp, se potessi dare un'occhiata ... –

+0

Inoltre, ho appena trovato la risposta al n. 2; domanda modificata ancora una volta con la risposta. –

Problemi correlati