verificar validar tengo studio programacion móviles multiusuario internet hacer desarrollo curso conexion aplicaciones java android database sqlite singleton

java - programacion - validar si tengo internet android studio



Android: no se puede realizar esta operación porque el grupo de conexiones se ha cerrado (6)

Estaba leyendo Stackoverflow sobre esta pregunta y todavía no he encontrado una solución. Noté que a veces, mi aplicación arroja este error:

java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed. at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:962) at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:599) at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348) at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894) ...

Tengo un archivo llamado DatabaseHelper.java usando este enfoque para obtener una instancia de este:

public static DatabaseHelper getInstance(Context context) { if (mInstance == null) { mInstance = new DatabaseHelper(context.getApplicationContext()); } return mInstance; }

Luego tengo métodos como este (que se estrelló en la línea cursor.moveToFirst () con ese error). Casi nunca falla, pero a veces lo hace.

public Profile getProfile(long id) { SQLiteDatabase db = this.getReadableDatabase(); String selectQuery = "SELECT * FROM " + TABLE_PROFILES + " WHERE " + KEY_PROFILES_ID + " = " + id; Cursor cursor = db.rawQuery(selectQuery, null); // looping through all rows and adding to list Profile profile = new Profile(); if (cursor.moveToFirst()) { doWhatEver(); } cursor.close(); db.close(); return profile; }

Entonces eso es todo en todos los métodos que uso:

SQLiteDatabase db = this.getReadableDatabase(); (or Writable)

Y luego cierro el cursor y el db. En este caso, el error se metió en la línea:

cursor.moveToFirst();

No veo por qué el error dice que el DB está cerrado si estoy llamando this.getReadableDatabase () antes. ¡Por favor apoya! Gracias :)


Actualmente tengo el mismo problema. Al eliminar el db.close () me resuelve el problema, creo que el problema está causado por el multi-threading. Aquí está mi investigación.

SQLiteOpenHelper contiene una referencia a SQLiteDatabase, cuando se llama a getReadableDatabase () o getWritableDatabase (), devolverá la referencia, si SQLiteDatabase está cerrado o es nulo, se creará un nuevo objeto SQLiteDatabase. Tenga en cuenta que dentro del método get, los códigos están protegidos en un bloque sincronizado.

SQLiteDatabase es una subclase de SQLiteClosable. SQLiteClosable implementa un esquema de conteo de referencia.

  • Cuando se creó por primera vez, el recuento es 1.

  • Cuando se ejecutan los métodos de operación de la base de datos (como insertar, consultar), aumentará el recuento y disminuirá el recuento cuando finalicen los métodos. Pero las operaciones del cursor NO están protegidas por el recuento de referencias.

  • Si el recuento disminuye a 0, el grupo de conexiones se cerrará y un objeto miembro SQLiteConnectionPool se establecerá como nulo, y ahora se cierra SQLiteDatabase;

  • SQLiteDatabase.close () disminuirá el recuento en 1;

Por lo tanto, si tiene un esquema de subproceso único, cerrar SQLiteDatabase estará bien porque SQLiteOpenHelper simplemente lo volverá a crear.

Si haces multi-threading, entonces te encontrarás con problemas. Supongamos que el subproceso A y el subproceso B llaman a getReadableDatabase () y SQLiteOpenHelper devuelve el SQLiteDatabase que contiene y, a continuación, el subproceso A finaliza su operación y llama a SQLiteDatabase.close (), ahora el subproceso del objeto SQLiteDatabase B tiene cerrado para que cualquier operación de base de datos posterior llamadas o métodos de cursor lanzarán la excepción.


Estoy teniendo el mismo problema, no he podido solucionarlo. He encontrado una pista posible: tengo un hilo de sincronización que se ejecuta todo el tiempo:

Item ii = dbHelper.popPendingUpload(); if (ii != null) upload(ii);

Y dentro de DBHelper

public Item popPendingUpload() { SQLiteDatabase db = getReadableDatabase(); Cursor res = db .rawQuery("SELECT * FROM items WHERE state = 0 LIMIT 1", new String[] {}); boolean hasNext = res.moveToFirst(); Item ii = null; if (hasNext) { ii = //load item } db.close(); return ii; }

El error también aparece en la llamada al método moveToFirst (). Como el hilo está sacando elementos en un bucle infinito, la primera vez funciona bien, la segunda vez que aparece el error. La parte interesante es que si pongo un punto de interrupción y paso por el código, el error ya no se muestra. Estoy probando en un dispositivo real con Android 4.1.

Lo sé, no es una respuesta, pero puede ayudar. Voy a seguir probando


Tal vez cierre la base de datos antes de acceder a la base de datos desde su aplicación.

Tienes que editar getProfile () para

public Profile getProfile(long id) { SQLiteDatabase db = this.getReadableDatabase(); try { String selectQuery = "SELECT * FROM " + TABLE_PROFILES + " WHERE " + KEY_PROFILES_ID + " = " + id; Cursor cursor = db.rawQuery(selectQuery, null); // looping through all rows and adding to list Profile profile = new Profile(); if (cursor.moveToFirst()) { doWhatEver(); } cursor.close(); finally { db.close(); } return profile; }


Tengo un error como el tuyo, aquí mi código:

try { String sql = "SELECT * FROM "+DB_TABLEDOWNLOAD; Cursor cursor = db.rawQuery(sql, null); //空双引号为原表没有的字段 String temp = ""; int existIconPath = cursor.getColumnIndex("iconPath"); int existAudioID = cursor.getColumnIndex("audioID"); if (existIconPath == -1 && existAudioID == -1){ temp = "url, downed,total,path,name, audioTitle, audioFileID,/"/",/"/""; }else if (existIconPath == -1 && existAudioID != -1){//iconPath不存在 temp = "url, downed,total,path,name, audioTitle, audioFileID,/"/",audioID"; }else if (existIconPath != -1 && existAudioID == -1){//audioID不存在 temp = "url, downed,total,path,name, audioTitle, audioFileID,iconPath,/"/""; }else { return; } db.beginTransaction(); String tempTableName = "_temp_"+DB_TABLEDOWNLOAD; String sqlCreateTemp = " ALTER TABLE "+DB_TABLEDOWNLOAD+" RENAME TO "+tempTableName+";"; db.execSQL(sqlCreateTemp); final String TB_TESTPAPERINFO_CREATE = "Create TABLE IF NOT EXISTS " + DB_TABLEDOWNLOAD + "(url TEXT, downed TEXT,total TEXT,path TEXT,name TEXT, audioTitle TEXT, audioFileID TEXT,iconPath TEXT, audioID TEXT);"; db.execSQL(TB_TESTPAPERINFO_CREATE); String sqlBackupData = "INSERT INTO "+DB_TABLEDOWNLOAD+" SELECT "+temp+" FROM "+tempTableName+";"; db.execSQL(sqlBackupData); String sqlDrop = "DROP TABLE IF EXISTS ''"+tempTableName+"'';"; db.execSQL(sqlDrop); db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); }finally{ db.endTransaction(); }

Utilizo return antes de db.beginTransaction (), mi código retorna antes de comenzar a Transaction, pero termino con Transaction finalmente. si no comienza Transacción y finalización, aparecerá la excepción.

así que revisa tu código sobre db.beginTransaction y endTransaction.


retirar

db.close();

Si intenta otra operación después de cerrar la base de datos, le dará esa excepción.

La documentation dice:

Lanza una referencia al objeto, cerrando el objeto ...

Además, consulte la excepción cerrada de Android Sq Lite sobre un comentario de un ingeniero de Android Framework que indica que no es necesario cerrar la conexión de la base de datos.


//close database after cursor is closed like: if(cursor.getCount() != 0){ while(cursor.moveToNext()){ //do operation } } cursor.close(); database.close();