close () не был явным вызовом для базы данных - PullRequest
2 голосов
/ 07 февраля 2011

Мне нужно знать, где вызывать db.close () в моем коде. Я добавил его в метод onCreate (), но когда мне нужно использовать некоторые методы, он говорит, что база данных не открыта, а затем я удалил из onCreate (), и он говорит, что close () не был вызван explicity. так где же мне закрыть, может ли это быть внутри каждого метода класса ??

вот код:

public class HoursPerDayDataHelper {

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

private Context context;
private SQLiteDatabase db;
OpenHelper openHelper = null;

public HoursPerDayDataHelper(Context context) {
    this.context = context;
    openHelper = new OpenHelper(this.context);
    this.db = openHelper.getWritableDatabase();
    openHelper.onCreate(db);

}

public void close() {

    if (openHelper != null) {
        openHelper.close();
    }

}

public void deleteAll() {
    this.db.delete(TABLE_NAME, null, null);
}

public String selectDuration(String date) {

    String duration = "";
    Integer value = 0;
    String returnment = "";
    Log.i(TAG, "date do select: " + date);              

    Cursor cursor = this.db.query(TABLE_NAME, new String[] { "duration" },
            "date = ? ", new String[]{ date }, null, null, null);

    Log.i(TAG, "cursor string " + cursor);

    if (cursor.moveToFirst()) {
        do {
            Log.i(TAG, "dentro do if cursor");
            duration = cursor.getString(0);
            value += Integer.parseInt(duration);

        } while (cursor.moveToNext());
        returnment = Integer.toString(value);
    }else{

        Log.i(TAG, "bla bla bla");

    }

    if (cursor != null && !cursor.isClosed()) {
        cursor.close();

    }
    return returnment;
}

public ArrayList<String[]> selectTopContacts() {

    ArrayList<String[]> list1 = new ArrayList<String[]>();
    Cursor cursor = this.db.query(TABLE_NAME, null, null, null, null, null,
            "duration desc");

    if (cursor.moveToFirst()) {
        do {
            if (cursor.getString(2) != "") {

                String[] data = new String[4];
                data[0] = cursor.getString(2);
                data[1] = cursor.getString(4);
                data[2] = cursor.getString(5);
                data[3] = cursor.getString(7);

                list1.add(data);

            } else {

                String[] data = new String[3];
                data[1] = cursor.getString(4);
                data[2] = cursor.getString(5);
                data[3] = cursor.getString(7);

                list1.add(data);

            }
        } while (cursor.moveToNext());
    }
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();

    }
    return list1;
}

public static class OpenHelper extends SQLiteOpenHelper {

    OpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS "
                + TABLE_NAME
                + "(id INTEGER PRIMARY KEY AUTOINCREMENT, duration TIME, date DATE, current_time TIME)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w("HoursPerDay Database",
                "Upgrading database, this will drop tables and recreate.");
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}

}

А это моя активность:

public class HoursPerDay extends Activity{

private String LOG_TAG = "HoursPerDay";
private TextView mDateDisplay;
public String date;
private int mYear;
private int mMonth;
private int mDay;
private int newDay;
private String hpdData; 
private HoursPerDayDataHelper hpd;

OpenHelper openHelper = new OpenHelper(HoursPerDay.this);

static final int DATE_DIALOG_ID = 0;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.hours_per_day);

    hpd = new HoursPerDayDataHelper(this);

    // capture our View elements
    mDateDisplay = (TextView) findViewById(R.id.dateDisplay);   

    // get the current date
    final Calendar c = Calendar.getInstance();
    mYear = c.get(Calendar.YEAR);
    mMonth = c.get(Calendar.MONTH);
    mDay = c.get(Calendar.DAY_OF_MONTH);
    // display the current date (this method is below)
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (openHelper != null) {
        openHelper.close();
    }
    if (hpd != null) {
        hpd.close();
    }
}

// the callback received when the user "sets" the date in the dialog
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {

    public void onDateSet(DatePicker view, int year, int monthOfYear,
            int dayOfMonth) {

        mYear = year;
        mMonth = monthOfYear;
        mDay = dayOfMonth;                  

        setBasicContent();

        hpd.close();


    }
};

protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DATE_DIALOG_ID:
        return new DatePickerDialog(this,
                    mDateSetListener,
                    mYear, mMonth, mDay);
    }
    return null;
}

@Override
public boolean onCreateOptionsMenu(Menu menu){

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.layout.hoursperdaymenu, menu);
    return true;

}

@Override
public boolean onOptionsItemSelected(MenuItem item){

    switch(item.getItemId()){

    case R.id.filter_by_day:            
            showDialog(DATE_DIALOG_ID);
            return true;
    case R.id.filter_by_user:

        showDialog(DATE_DIALOG_ID);
        return true;

    default:
        return super.onOptionsItemSelected(item);
    }

}   

public void setBasicContent() {

    date = (mMonth + 1) + "/" + newDay + "/" + mYear;       
    hpdData = this.hpd.selectDuration(date);
    mDateDisplay.setText(hpdData);
    hpd.close();
}

}

Ответы [ 2 ]

2 голосов
/ 07 февраля 2011

Я думаю, что есть 2 способа:

  • в onPause -метод и отметьте там isFinishing, если да -> закрыть. Проблема: если ваше приложение убито app-killer, база данных остается открытой.
  • Вы открываете и закрываете БД каждый раз (методы), которые вы читаете / пишете.

EDIT:
Хорошо, я понимаю, почему это может быть вызвано. Я думаю, вы неправильно поняли использование SQLiteOpenHelper. Вам никогда не придется вызывать onCreate -метод.
Конечно, лучший способ - создать класс DBHelper и использовать его в отдельных вызовах, скажем, SQLDataHandler.
Ваша деятельность выглядит хорошо. Я изменил несколько вещей, посмотрите, поможет ли это. Я отмечу их:

Это все, что должно быть в классе Helper:

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

Просто оставьте его CREATE TABLE он будет создан / вызван, только если он не существует.
Я видел ошибки, возникающие при прямой передаче строки

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

Для использования:
Просто позвоните в ваш DataHandler класс:

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

Все другие вещи, такие как удаление, добавление и т. Д., Должны выполняться в классе «DataHandler».
Просто используйте те же два метода, чтобы получить вашу БД. В конце, когда вы закончите, вы звоните только в вас DataHandler класс db.close().
Таким образом, сама деятельность никогда не использует де БД напрямую. Думаю, лучше практиковаться;)

Надеюсь, это поможет. По любым другим вопросам просто задавайте:)


EDIT2:

Во-первых, в общем случае он должен работать с внутренним классом.
НО: если вы хотите добавить другую таблицу из другого класса, она больше не будет работать. Вот почему это лучший способ поместить его в отдельный класс с самого начала. Его можно использовать многократно (с небольшими изменениями).
Поместите код, который я разместил в вашем классе OpenHelper. Ничего больше.
Затем поместите материал для манипулирования данными в класс, который называется что-то вроде: DataHandlerDB .

Пример кода:

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

Для повышения эффективности используются методы static, вам не нужно создавать объекты.
Используйте это так: В своей деятельности

    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 голосов
/ 07 февраля 2011

если открыть в onCreate, затем закрыть в onDestroy

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...