什么时候关闭bbdd并关闭光标?

时间:2012-01-06 10:43:31

标签: android database sqlite cursor

任何人都可以教我什么时候我应该关闭一个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时?

1 个答案:

答案 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;
    }
}

您可以将其用作案例的模板。