任何人都可以教我什么时候我应该关闭一个sqlite open bbdd和一个游标?
我有这个班级
public class DataBaseHelper
{
Context context;
private static final String DATABASE_NAME="lugaresbbdd";
private SQLiteDatabase db; // Referencia al manager.
private final int DB_VERSION = 1; // version
CustomSQLiteOpenHelper helper;
// Nombres para las tablas y campos
private final String TABLE_NAME = "lugares";
private final String TABLE_ROW_ID = "_id";
static String CNOMBRE = "nombre";
private final String CDESC = "descripcion";
private final String CLAT = "latitud";
private final String CLONG="longitud";
static String CFOTO="foto";
public DataBaseHelper(Context context)
{
this.context = context;
//Crea o abre la BBDDD
CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
db = helper.getWritableDatabase();
}
public Cursor getNombres(){
//CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
//db = helper.getWritableDatabase();
Cursor respuesta = db.rawQuery("select "+TABLE_ROW_ID+","+CNOMBRE+" from "+TABLE_NAME, null);
return respuesta;
}
而且:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listatab);
context = getBaseContext();
//Creamos la instancia de DataBaseHelper, un cursor y aplicamos el metodo getNombres al cursor y llamamos al metodo encargado de gestioanr ese cursor
ayudabbdd = new DataBaseHelper(this);
nombresC = (Cursor) ayudabbdd.getNombres();
startManagingCursor(nombresC);
nombresC.moveToFirst();
//Para crear un simpleCursorAdapter necesitamos
//Contexto this
//Layour donde se mostrara el resultado, generalmente un textview
//Cursor
//Cual sera el campo que recibiremos de la BBDD
//Donde tenemos que poner esa informacion, generalmente el ID correspondiente al textvies del layour del segundo parametro
String[] deNombre = new String[]{DataBaseHelper.CNOMBRE};
int[] aNombre = new int[]{R.id.nombreLugar};
lugaresNombre = new SimpleCursorAdapter(this, R.layout.entrada_lista, nombresC, deNombre, aNombre);
setListAdapter(lugaresNombre);
listaview= getListView();
listaview.setOnItemClickListener(this);
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent intent = new Intent(listatab.this, mostrarLugar.class);
startManagingCursor(nombresC);
String nombreClicks= nombresC.getString(nombresC.getColumnIndex("nombre"));
intent.putExtra("nombre",nombreClicks);
startActivity(intent);
nombresC.close();
}
@Override
public void onDestroy()
{
nombresC.close();
ayudabbdd.close();
super.onDestroy();
}
@Override
protected void onPause() {
nombresC.close();
ayudabbdd.close();
super.onPause();
}
在第二课中,如果我点击一个项目,日志猫说:
android.database.sqlite.DatabaseObjectNotClosedException:应用程序未关闭此处打开的游标或数据库对象
但是如果我在onCreate方法中关闭光标,不要在列表视图中填充,那么,当我必须关闭游标nombresC时?
答案 0 :(得分:2)
我不确切知道,但我认为你必须在活动的onResume方法中打开数据库并关闭onPause。对于游标,你应该在你不需要它们之后关闭它们。例如,如果您的数据库助手类因查询而返回游标,则应在处理游标的所有行时关闭它。
我建议你考虑记事本的例子。如何在Android中使用数据库有一些非常好的技巧。
更新:以下是我通常在活动中填充列表的示例:
public class AcWords extends Activity {
/** Called when the activity is first created. */
DbWordsAdapter dbWordsAdapter;
ListView vw;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_words);
vw = (ListView) findViewById(R.id.ac_words_lv_words);
dbWordsAdapter = new DbWordsAdapter(this);
dbWordsAdapter.open();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
SimpleCursorAdapter adtWord = new SimpleCursorAdapter(this, R.layout.ac_words_vw_wordrow,
dbWordsAdapter.getWordsOrderedByAlph(),
new String[] { DbWordsAdapter.C_WORD, DbWordsAdapter.C_EXPLANATION },
new int[] { R.id.ac_words_vw_wordrow_tv_word, R.id.ac_words_vw_wordrow_tv_explanation });
vw.setAdapter(adtWord);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
dbWordsAdapter.close();
}
}
这是我的助手班:
public class DbWordsAdapter {
private static final String TAG = DbWordsHelper.class.getSimpleName();
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static DbWordsHelper dbWordsHelper;
private Context context;
private SQLiteDatabase mDb;
// database constants
private static final String DB_NAME = "words.db";
private static final int DB_VERSION = 1;
private static final String TABLE_WORDS = "words";
// database columns names
public static final String C_ID = BaseColumns._ID;
public static final String C_WORD = "word";
public static final String C_EXPLANATION = "explanation";
public static final String C_CREATION_DATE = "creation_date";
//Sql Statements
static final String CREATE_TABLE_WORDS = "create table " + TABLE_WORDS
+ "(" + C_ID + " integer primary key autoincrement, " + C_WORD
+ " text not null, " + C_EXPLANATION + " text, "
+ C_CREATION_DATE + " date not null)";
static final String DROP_TABLE_WORDS = "drop table if exists "
+ TABLE_WORDS;
static final String[] ALL_COLUMNS = { C_ID, C_WORD, C_EXPLANATION,
C_CREATION_DATE };
static final String ORDER_BY_DATE = C_CREATION_DATE + " desc";
static final String ORDER_BY_ALPH = C_WORD + " asc";
static final String ORDER_BY_RANDOM = "random() limit 1";
/*
* Inner class that manages database creation and management
*/
private static class DbWordsHelper extends SQLiteOpenHelper {
private DbWordsHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "SqlCreate Statement: "
+ CREATE_TABLE_WORDS);
try {
db.execSQL(CREATE_TABLE_WORDS);
} catch (SQLException e) {
Log.e(TAG, "Error while creating database" + TABLE_WORDS, e);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Here in the future should be method that change the schema of the
// database. Now we just delete
try {
db.execSQL(DROP_TABLE_WORDS);
} catch (SQLException e) {
Log.e(TAG, "Error while updating database" + TABLE_WORDS, e);
}
onCreate(db);
}
}
public DbWordsAdapter(Context context) {
this.context = context;
}
public DbWordsAdapter open () {
if (dbWordsHelper == null) {
dbWordsHelper = new DbWordsHelper(context);
}
mDb = dbWordsHelper.getWritableDatabase();
return this;
}
public void close () {
dbWordsHelper.close();
dbWordsHelper = null;
}
public Cursor getWordDetails(long rowId) {
Log.d(TAG, "getWordDetails method");
Cursor mCursor = mDb.query(TABLE_WORDS, ALL_COLUMNS, C_ID + "=?",
new String[] { String.valueOf(rowId) }, null, null, null);
return mCursor;
}
}
您可以将其用作案例的模板。