何时关闭 bbdd 以及何时关闭光标?

发布于 2024-12-25 00:05:42 字数 3359 浏览 2 评论 0原文

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

anyone can teach me when i should to close a sqlite open bbdd and a cursor?

I have this class

    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;

    }

And this:

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

In the second class if i click on a item log cat said me:

android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

But if i close the cursor in onCreate method, don't populate me the list view, then, when i must to close the cursor nombresC?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凯凯我们等你回来 2025-01-01 00:05:43

我不太清楚,但就我而言,我认为您必须在活动的 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;
    }
}

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

I don't know precisely, but for my opinion I think that you have to open database in onResume method of your activity and close it onPause. As for Cursors you should close them after you do not need them. For instance, if your database helper class returns cursor as a result of query then you should close it when you process all rows of the cursor.

I advice you to consider Notepad example. There are some very good tips how to work with databases in Android.

UPDATE: Here is an example how I usually populate my list in an activity:

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

}

And this is my helper class:

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

You can use it as a template for your case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文