Autore Topic: SQLite - attempt to re-open an already-closed object  (Letto 842 volte)

Offline wlf

  • Utente normale
  • ***
  • Post: 334
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
SQLite - attempt to re-open an already-closed object
« il: 13 Ottobre 2014, 16:21:25 CEST »
0
Salve,
nell'utilizzo di SQLite ho spesso l'errore in oggetto "attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.example.prova/databases/miodb"

Nella onCreate della activity dichiaro il mio Dbadapter

Codice: [Seleziona]
dataSource = new DbAdapter(this);
dataSource.open();

... nella onPause lo chiudo:
Codice: [Seleziona]
dataSource.close();
... nella onResume lo riapro:
Codice: [Seleziona]
dataSource.open();
A quanto pare l'errore si presenta soprattutto quando lo smartphone va in pause; avendo anche un asyncTask questo praticamente continua a girare e praticamente può capitare che acceda al datasource dopo che ho già abbandonato l'activity.

Se non erro sarebbe buona cosa aprire il datasource alla resume e chiuderlo alla onPause, ma considerando gli errori suppongo che non sia l'approccio più corretto.
Sono quindi a chiedere suggerimenti in merito; dovrei utilizzare un datasource che apro e chiudo dentro all'asyncTask?

Grazie! ;)

Offline marco4098

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    galaxys2
  • Sistema operativo:
    win8
Re:SQLite - attempt to re-open an already-closed object
« Risposta #1 il: 13 Ottobre 2014, 18:25:39 CEST »
0
Che io sappia è buona cosa aprire e chiudere in onStart e onStop; riguardo l'asynkTask non so bene cosa tu voglia fare, ma considerando che l'asynkTask è indipendente dal ciclo di vita della tua app di solito gli si fanno eseguire operazione che prescindono dal fatto che l'app sia aperta o meno e di conseguenza non interagiscono direttamente con essa.

Offline wlf

  • Utente normale
  • ***
  • Post: 334
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:SQLite - attempt to re-open an already-closed object
« Risposta #2 il: 14 Ottobre 2014, 09:49:33 CEST »
0
Che io sappia è buona cosa aprire e chiudere in onStart e onStop;

Quindi mi coviene spostare l'apertura e chiusura del datasource rispettivamente sulla onStart e sulla onStop? Casomai non mi conviene spingermi sulla onCreate e onDestroy?

Citazione
riguardo l'asynkTask non so bene cosa tu voglia fare, ma considerando che l'asynkTask è indipendente dal ciclo di vita della tua app di solito gli si fanno eseguire operazione che prescindono dal fatto che l'app sia aperta o meno e di conseguenza non interagiscono direttamente con essa.

In questo caso l'asyncTask si occupa di fare il download di dati in JSON e scriverli appunto sul DB dell'App; ma visto che si tratta di un task asincrono indipendente dal ciclo di vita dell'activity può capitare che vada a scrivere quando l'utente è già passato ad un altra activity o ha addirittura chiuso l'App. In questo caso eventualmente mi conviene allora aprire e chiudere il datasource rispettivamente nella onPreExecute e onPostExecute del mio asyncTask?

Offline marco4098

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    galaxys2
  • Sistema operativo:
    win8
Re:SQLite - attempt to re-open an already-closed object
« Risposta #3 il: 14 Ottobre 2014, 20:42:24 CEST »
0
No se non per casi in cui non puoi fare diversamente  apri e chiudi in start/stop, per il task ovviamente se l'activity o l'app è chiusa ovviamente dovresti  aprire e chiudere il DB all'interno del task, se dovessi avere problemi nell'interagire con il DB ad app chiusa allora mi sa che ti serve un content provider

Offline Hero80

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Honor 6
  • Sistema operativo:
    Windows 7
Re:SQLite - attempt to re-open an already-closed object
« Risposta #4 il: 16 Dicembre 2014, 23:13:50 CET »
0
Prova, prima di aprire o chiudere la connessione di verificarne lo stato cioè ad esempio quando lo apri
Codice (Java): [Seleziona]
if(!database.isOpen()){ database.open();} e quando lo devi chiudere
Codice (Java): [Seleziona]
if(database.isOpen()){ database.close();}

Offline wlf

  • Utente normale
  • ***
  • Post: 334
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:SQLite - attempt to re-open an already-closed object
« Risposta #5 il: 14 Gennaio 2015, 14:31:46 CET »
0
Prova, prima di aprire o chiudere la connessione di verificarne lo stato cioè ad esempio quando lo apri
Codice (Java): [Seleziona]
if(!database.isOpen()){ database.open();} e quando lo devi chiudere
Codice (Java): [Seleziona]
if(database.isOpen()){ database.close();}

L'errore "attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.example.prova/databases/miodb" non mi viene dato nel tentativo di aprire il db, ma nella classe DbAdapter, quando chiamo uno dei metodi che accedono al db. Avevo quindi aggiunto un controllo tipo:

Codice: [Seleziona]
                if (!database.isOpen()) {
                        return database.isOpen();
                }

A mio avviso rimane comunque un approccio sbagliato; se il db viene aperto e chiuso rispettando il ciclo di vita dell'activity ma nella stessa parte un asyncTask e questo accede al db bisogna fare in modo che l'asyncTask possa comunque comunicare con il db anche se l'activity è andata in pause. ;)

Offline wlf

  • Utente normale
  • ***
  • Post: 334
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:SQLite - attempt to re-open an already-closed object
« Risposta #6 il: 11 Giugno 2015, 11:55:20 CEST »
0
Ritorno sull'argomento aggiungendo altra carne al fuoco ... :)

Se utilizzo il dataSource unicamente sull'AsynckTask potrei spostare la dataSource.open() nella onPreExecute() e la dataSource.close() nella onPostExecute(Boolean). Ma se ho la necessità di usarlo anche dentro all'activity mettendolo nella onStart e onStop come consigliato rischio comunque di trovarmi il dataSource chiuso! :(

Posso dichiarare 2 o più dataSource che accedono allo stesso DB contemporaneamente? Oppure le connessioni al DB sono univoche?