2012-01-06 72 views
0

任何人都可以教我什么时候应该关闭一个打开bbdd和光标的sqlite?何时关闭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?

回答

2

我不知道确切的,但对我的意见,我认为你必须打开你的活动的onResume方法的数据库,并关闭它onPause。至于光标,你应该在你不需要它们后关闭它们。例如,如果您的数据库帮助程序类作为查询的结果返回游标,那么在处理游标的所有行时应关闭它。

我建议你考虑记事本的例子。有一些非常好的提示如何在Android中使用数据库。

UPDATE:下面是一个例子,如何我通常填充在活动中我的名单:

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

你可以使用它作为一个模板为你的情况。

+0

林编辑我的代码更容易回应我 – colymore 2012-01-06 13:53:04

+0

我已经添加了一个更新到我的答案。 – Yury 2012-01-06 14:32:55