Je veux faire SQLiteOpenHelper avec quelques méthodes supplémentaires (comme getStreetsCursor) qui retourne des données de mon DB. Donc, je l'ai écrit quelque chose comme ceci:android SQLiteOpenHelper et les fuites
public class DBHelper extends SQLiteOpenHelper {
public static final String DB_NAME="some.db";
public static final String T1_NAME="streets";
public static final String T1_FNAME1="name";
public static final String T2_NAME="addresses";
public static final String T2_FNAME1="name";
public static final String T2_FNAME2="address";
private Context appContext;
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
appContext=context;
}
public Cursor getStreetsCursor(String chars) {
SQLiteDatabase dbReadable=this.getReadableDatabase();
Cursor curStreets = dbReadable.query(DBHelper.T1_NAME,
new String[] {"_id",DBHelper.T1_FNAME1},
DBHelper.T1_FNAME1+" LIKE(\""+chars.toUpperCase()+"%\")",
null, null, null, DBHelper.T1_FNAME1);
return curStreets;
}
Il existe plusieurs méthodes comme getStreetsCursor (getAddresses, getAddress4 etc.) définis dans DBHelper. Je suppose que si c'est un DB Helper il devrait certainement avoir de telles méthodes, je veux dire le DBHelper est un espace réservé logique pour eux.
Ce que je fais dans l'activité est de créer une nouvelle instance DBHelper et de la stocker dans un champ privé (appelé mDBHelper) d'activité. De plus, dans la méthode d'activité onDestroy, j'ai mDBHelper.close().
private DBHelper mDBHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDBHelper = new DBHelper(this);
...
@Override
protected void onDestroy() {
if (mDBHelper!=null){
mDBHelper.close();
Log.i(APP_TAG,"mDBHelper.close() in "+this.getClass());
}
super.onDestroy();
}
Ces activités utilise le mDBHelper que d'une manière - en l'appelant est des méthodes personnalisées comme mDBHelper.getStreetsCursor(). Finalement, j'ai trouvé un message d'exception dans logcat à propos de mon application a des fuites dans de telles activités qui utilise DBHelper. Il dit quelque chose comme "la base de données n'a jamais été fermée". J'ai donc décidé d'ajouter un appel à la méthode close() dans chacune de mes méthodes personnalisées juste avant le retour. Il semble donc que:
public Cursor getStreetsCursor(String chars) {
SQLiteDatabase dbReadable=this.getReadableDatabase();
Cursor curStreets = dbReadable.query(DBHelper.T1_NAME,
new String[] {"_id",DBHelper.T1_FNAME1},
DBHelper.T1_FNAME1+" LIKE(\""+chars.toUpperCase()+"%\")",
null, null, null, DBHelper.T1_FNAME1);
dbReadable.close();
return curStreets;
}
Maintenant, j'ai obtenu aucune fuite mais nous avons eu le problème suivant - seulement le premier appel à mDBHelper.getStreetsCursor() exécute vraiment. Tous les appels suivants renvoient null. C'est dû à dbReadable.close(); ligne. Si je l'enlève tout fonctionne bien mais j'ai encore des fuites. Donc, je ne peux pas comprendre ce qui ne va pas. Dans chaque méthode personnalisée, j'ai obtenu SQLiteDatabase dbReadable = this.getReadableDatabase(); ligne qui devrait renvoyer une instance lisible, mais après l'exécution de la méthode close() ce n'est pas le cas. Je pense qu'il s'agit de mes méthodes personnalisées car elles appellent .getReadableDatabase() dans une instance de DBHelper. Si je place ces méthodes directement dans l'activité tout fonctionne bien - pas d'exception de fuite et chaque fois que les méthodes renvoient des données correctes. Mais je veux placer ces méthodes dans ma classe DBHelper. Donc, la question principale est - quel est le problème et comment le faire correctement?
thanx. bonne idée. – Stan