Я хочу создать SQLiteOpenHelper с некоторыми дополнительными методами (например, getStreetsCursor), который возвращает данные из моей базы данных.Поэтому я написал что-то вроде этого:
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;
}
Существует несколько методов, таких как getStreetsCursor (getAddresses, getAddress4 и т. Д.), Определенных в DBHelper.Я предполагаю, что если это DB Helper , он определенно должен иметь такие методы, я имею в виду, что DBHelper является для них логическим заполнителем.
Что я делаю в этом упражнении, так это создаю новый экземпляр DBHelper ихраните его в приватном поле (называемом mDBHelper) деятельности.Кроме того, в методе действия onDestroy у меня есть 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();
}
Эти действия используют mDBHelper только одним способом - вызывая его пользовательские методы, такие как mDBHelper.getStreetsCursor ().В конце концов я нашел сообщение об исключении в logcat о том, что мое приложение получило утечки в таких действиях, которые используют DBHelper.Там написано что-то вроде «база данных никогда не была закрыта».Поэтому я решил добавить вызов метода close () в каждый из моих пользовательских методов непосредственно перед возвратом.Так это выглядит так:
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;
}
Теперь у меня нет утечек, но возникла следующая проблема - действительно выполняется только первый вызов mDBHelper.getStreetsCursor ().Все последующие вызовы возвращают ноль.Это связано с dbReadable.close ();линия.Если я удаляю его, все работает нормально, но я снова получаю утечки.Так что я не могу понять, что происходит не так.В каждом пользовательском методе я получил SQLiteDatabase dbReadable = this.getReadableDatabase ();строка, которая должна возвращать читаемый экземпляр, но после выполнения метода close () это не так.Я думаю, это о моих пользовательских методах, потому что они вызывают .getReadableDatabase () внутри экземпляра DBHelper.Если я помещаю эти методы непосредственно в действие, все работает нормально - исключений утечки нет, и каждый раз методы возвращают правильные данные.Но я хочу разместить эти методы в моем классе DBHelper.
Итак, главный вопрос - что не так и как это сделать правильно?