2011-12-16 5 views
12

Nella mia app Android, utilizzo SQLiteOpenHelper per implementare ContentProvider. Le operazioni di query, aggiunta, cancellazione sono tutte tramite ContentProvider.Quando dovrei chiamare close() su SQLiteOpenHelper utilizzato da ContentProvider

Ma in uno dei miei telefoni Android (htc g13), ho trovato il file * .db-wal nella directory/data/data/[nome pacchetto]/database. E le dimensioni del file aumentano molto velocemente quando si utilizza ContentProvider. Occupava troppo spazio nella RAM dell'utente.

Si consiglia di chiudere SQLiteOpenHelper per risolvere il mio problema (è utile) nel post enter link description here.

Ma voglio trovare un "luogo" per aggiungere il metodo "close()" poiché non sto usando SQLiteOpenHelper direttamente (usando tramite ContentProvider). il metodo query() in ContentProvider deve restituire un cursore e SQLiteDatabse deve rimanere nello stato aperto.

Sono confuso, che spettacolo faccio ora per mantenere * .db-wal andato e utilizzare ContentProvider normalmente?

+2

Questo è un thread precedente ma ancora pertinente su Google, ecco un riferimento alla risposta corretta: http: // stackoverflow.it/questions/4547461/closing-the-database-in-a-contentprovider – saulobrito

+0

Penso che questa sia la migliore risposta, grazie. – cmoaciopm

+0

Leggi questa fantastica spiegazione e non è necessario chiudere il db durante l'utilizzo di contentProvider. Http://stackoverflow.com/questions/14002022/android-sq-lite-closed-exception/25379071#25379071 – Nepster

risposta

5

avete un paio di casi per coprire:

1) Quando i tuoi finiture di applicazione (ad esempio, entrando OnDestroy()) assicurarsi di chiudere tutti i cursori, le istanze di database di SQLiteDatabase e SQLiteOpenHelpers (utilizzando il modello se (collegamento .isOpen()) object.close())

2) Quando l'applicazione va in pausa() -> onResume() - utilizzare queste fasi in modo appropriato per sospendere/riprendere la connessione o per chiuderle/aprirle.

È buona norma chiudere il database immediatamente dopo aver terminato di utilizzarlo. La banca dati viene memorizzato nella cache, quindi non c'è nessun problema di chiuderlo e ri-acquisire esempio di nuovo quando ne avete bisogno con getWritableDatabase()/getReadableDatabase()

Dal documento ufficiale: "Una volta aperto con successo, il database viene memorizzato nella cache, in modo da poter chiamare questo metodo ogni volta che è necessario scrivere nel database. (Assicurati di chiamare close() quando non hai più bisogno del database.) "

Inoltre, tenere presente che se SQLiteOpenHelper memorizza nella cache e tiene traccia di tutti Aprire istanze di SQLiteDatabase, significa fondamentalmente che se non si lasciano le connessioni aperte al database, non sarà necessario chiamare close su SQLiteOpenHelper.

Si consiglia di chiudere tutti i cursori e i database immediatamente dopo aver smesso di utilizzarli. Cerca sempre di applicare le operazioni try/catch/for query e infine blocca per chiamare i metodi close sugli oggetti.

+0

Grazie hovanessyan! Ma ciò che mi turba è il mio supporto multi-thread, non so "quando" il database non è realmente necessario all'app. Il secondo problema è: quello che sto affrontando è ContentProvider (forse ContentResolver sarà esatto), dal punto di progettazione del livello, non riesco a ottenere il riferimento di SQLiteDatabase o SQLiteOpenHelpers easilly. Odio il concetto di ContenProvider! – cmoaciopm

+0

se si utilizzano thread separati per le chiamate DB, presumo che userete AsyncTasks. In tal caso, esegui tutte le operazioni in doInBackground() e chiudi oggetti in onPostExecute(). Non riuscivo a capire l'altro problema. Puoi approfondire questo punto di progettazione del livello>? – hovanessyan

+1

Ho provato la logica come il tuo suggerimento, ma ho ottenuto un'eccezione come "database già chiuso". Penso che il codice esegua seq come di seguito: 1. thread A getWritableDatabase(); 2. thread B chiude database; 3. thread A esegue query sql ed è successo l'eccezione! – cmoaciopm

6

L'ingegnere di framework Android rinvia a questa vista che è necessario chiudere il DB.

Come da Dianne Hackborn (Android Ingegnere quadro) in this thread:

Un fornitore di contenuti viene creato quando viene creato il suo processo di hosting, e rimane in giro per tutto il tempo del processo fa, quindi non c'è bisogno a chiude il database - verrà chiuso come parte del kernel pulendo le risorse del processo quando il processo viene terminato.

Problemi correlati