Bonjour à tous,

J'ai un souçis avec l'utilisation de Sqlite et notamment au niveau des curseurs.

J'ai un helper qui gère les intéractions avec ma base de données :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
public long add(Groupes grp)
{
	ContentValues values = new ContentValues();
	if(!exist(grp.getLibelle()))
	{
		values.put("libelle", grp.getLibelle());
		return sql.insert(TABLE, null, values);
	}
	return -1;
}
 
public boolean exist(String nom)
{
	Cursor c = sql.rawQuery("SELECT _id FROM groupes WHERE libelle = ?", new String[]{nom});
	if(c != null)
	{
		if(c.getCount() > 0)
			return true;
	}
	c.close();
	return false;
}
 
public void close(){db.close();}
public void finalize(){if (db!=null) db.close()}
La méthode exist n'est pas pertinante puisque une condition d'unicité sur la table serait plus adaptée mais c'est pas le pb ici

Dans mon activity j'ai un événement qui me permet d'écrire dans la base :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
public void onClick(DialogInterface dialog, int which) {
	Context ctx = Ajouter.this;
	String groupe = input.getText().toString();
	if(groupe.length() > 0)
	{
		Groupes grp 			= new Groupes(input.getText().toString());
		GroupesDBAdapter gDb 	= new GroupesDBAdapter(ctx);
		int idGrp 				= (int) gDb.add(grp);
		if(idGrp == -1)
			Toast.makeText(ctx, R.string.grouperroradd, Toast.LENGTH_SHORT).show();
		else
		{
			grp.setId(idGrp);
			Toast.makeText(ctx, R.string.groupadded, Toast.LENGTH_SHORT).show();
			adapter.add(grp);
		}
 
		gDb.close();
 
	}
}
J'ai lu un peu partout qu'il était important de fermer les curseur et les connexions à la base dès que possible , ce que je fais (enfin il me semble). J'ai aussi pu lire qu'il fallait dans l'activity utilisé startManagingCursor et stopManagingCursor quand des curseur sont passé à l'activité mais je ne rentre pas dans ce cas , ou alors j'ai mal compris.

Bref quand je fait un ajout dans la base j'ai une levée d'exception :
05-27 14:11:50.940: ERROR/Cursor(6137): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
05-27 14:11:50.940: ERROR/Cursor(6137): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210)
05-27 14:11:50.940: ERROR/Cursor(6137): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
05-27 14:11:50.940: ERROR/Cursor(6137): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
05-27 14:11:50.940: ERROR/Cursor(6137): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1315)
05-27 14:11:50.940: ERROR/Cursor(6137): at pry.pocket.db.GroupesDBAdapter.exist(GroupesDBAdapter.java:88)
qui si je comprend bien me dis gentiment qu'un curseur est finalisé sans avoir été fermé ...

Une idée de ce que je fait mal dans ma gestion de ressource ? un db.close() dans le deconstructeur est il suffisant ou dois je fermer ma connexion après chaque requête ?