close() was not explicity called on database

前端 未结 2 2120
挽巷
挽巷 2021-01-22 10:18

I need to know where to call the db.close() in my code. I\'ve added it on onCreate() method, but when I need to use some methods it says database not open, and then I\'ve remove

相关标签:
2条回答
  • 2021-01-22 10:27

    if you open in onCreate, then close in onDestroy

    0 讨论(0)
  • 2021-01-22 10:44

    I think there are 2 ways:

    • in onPause-method and check there isFinishing if yes -> close. Problem: if your app gets killed by app-killer, db remains open.
    • You open and close the DB each time (methods) you read/write.

    EDIT:
    Ok, I see why it could be caused. I think you misunderstood the usage of the SQLiteOpenHelper. You never have to call the onCreate-method.
    Defently the better way is to make a DBHelper class and use it in a separate calls, lets say SQLDataHandler.
    Your activity look good. I changed a few things, look if it helps. I'll mark them:

    That's all what should be in the Helper class:

    public static class OpenHelper extends SQLiteOpenHelper {
    
     private static final String DATABASE_NAME = "database.db";
     private static final int DATABASE_VERSION = 1;
     protected static final String TABLE_NAME = "table";
     protected String TAG = "HoursPerDayDataHelper";
    

    Just leave it CREATE TABLE it gets only created/called if there isn't one existing.
    I have seen errors occurring if the String is passed directly

     @Override
     public void onCreate(SQLiteDatabase db) {
    
        String query = "CREATE TABLE "
                   + TABLE_NAME
                   + "(id INTEGER PRIMARY KEY AUTOINCREMENT, duration TIME, date DATE,          current_time TIME)";
        db.execSQL(query);
        }
     }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
    }
    
     OpenHelper(Context context) {
         super(context, DATABASE_NAME, null, DATABASE_VERSION);
     }
    }
    

    To use it:
    Just call in your DataHandler class :

    OpenHelper helper = new OpenHelper(ctx);
    // SQLiteDatabase db = helper.getReadableDatabase();
    SQLiteDatabase db = helper.getWritableDatabase();
    

    All other stuff, like deleting, adding and so on, should be done in a "DataHandler" class.
    Just use the same two methods there to get your DB. At the end, when you are finished, you call just in you DataHandler class db.close().
    Like this the activity itself never uses de DB directly. Better practice I think ;)

    I hope it helps. For any other questions, just ask :)


    EDIT2:

    First, in general it should work with a inner class.
    BUT: In case you want to add another table from another class it won't work anymore. Thats why it's the better way to put it in a separate class from beginning. It's even reusable (with some smal adjustments).
    Put the code I posted in your class OpenHelper. Nothing more.
    Then, put the data manipulation stuff in a class called something like: DataHandlerDB.

    Code example:

    package ...;
    
    import java.util.ArrayList;
    import java.util.List;
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    
    public class DataHandlerDB {
    
      public static void persistAll(Context ctx, List<Module> moduleList) {
    
          DatabaseHelper helper = new DatabaseHelper(ctx);
    
          SQLiteDatabase db = helper.getWritableDatabase();
    
          ContentValues values = new ContentValues();
          for (Module m : moduleList) {
    
              values.put("_id", m.get_id());
              values.put("name", m.getModule());
    
              db.insert("module", null, values);
          }
          db.close();
      }
    
      public static List<Module> findAll(Context ctx) {
    
          List<Module> result = new ArrayList<Module>();
          DatabaseHelper helper = new DatabaseHelper(ctx);
          SQLiteDatabase db = helper.getReadableDatabase();
    
          Cursor c = db.query(ModuleDB.TABLE_NAME, new String[] { ModuleDB.ID,
                ModuleDB.MODULE}, null, null, null, null, null);
    
          while (c.moveToNext()) {
              Module m = new Module(c.getInt(0), c.getString(1));
              result.add(m);
          }
          c.close();
          db.close();
    
          return result;
      }
    
      // Update Database entry
      public static void update(Context ctx, Module m) {
    
          DatabaseHelper helper = new DatabaseHelper(ctx);
          SQLiteDatabase db = helper.getWritableDatabase();
          ContentValues values = new ContentValues();
    
          values.put("_id", m.get_id());
          values.put("name", m.getModule());
    
          db.update("module", values, null, null);
          db.close();
      }
    
      public static void delete(Context ctx, Module m) {
    
          DatabaseHelper helper = new DatabaseHelper(ctx);
          SQLiteDatabase db = helper.getWritableDatabase();
          ContentValues values = new ContentValues();
    
          values.put("_id", m.get_id());
          values.put("name", m.getModule());
    
          db.delete("module","_id = m.get_id()", null);
          db.close();
      }
    
      public static void createDB(Context ctx) {
          DatabaseHelper helper = new DatabaseHelper(ctx);
          SQLiteDatabase db = helper.getWritableDatabase();
          db.close();
      }
    }
    

    In order to be more efficient the methods are static, you won't need to create objects.
    Use it like this: In your activity

        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
                // get the a writable DB, in case it's not existing it gets created.
        DataHandlerDB.createDB(this);
        // get stuff out of DB
        moduleList = DataHandlerDB.findAll(this);
    
        adapter = new ArrayAdapter<Module>(this,
                android.R.layout.simple_list_item_1, moduleList);
        setListAdapter(adapter);
    }
    
    0 讨论(0)
提交回复
热议问题