Android SQLite:何时以及在哪里初始化SQLiteOpenHelper

5

我在我的应用程序中使用SqlLite非常困难;

我已经设置了一个扩展自SQLiteOpenHelper的数据库帮助程序类。

public class DatabaseHelper extends SQLiteOpenHelper {

在OnCreate中,我正在创建约6个表:
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE myTestTable (Id INTEGER PRIMARY KEY , "
            + "info TEXT," + 
            + "TopLeft TEXT")); <-- example insert

}

当我的应用程序启动时,我正在解析一些xml并将数据输入表中,我已经检查了数据库,所有内容都在那里,并且我的表已经正确创建。但是当我调用数据时,它就消失了!在dbhelper类中有许多不同的查询,在每个活动中重新初始化该类,以便我可以访问类中的函数。我认为这不是正确的方法,因为它会再次运行我的oncreate并清除所有表格(或者至少在我尝试从中调用数据之后,它会出现这种情况,因为它是空的!)。我原本认为oncreate只运行一次,但显然情况并非如此,因为它似乎每次都在重新创建我的数据库并清除我的数据!你应该在哪里初始化dbhelper类,并如何停止重新创建表格?即使应用程序关闭,我也需要数据持久存在!我很困惑!如果这没有意义,请具体提问我如何澄清它!更新:我发现可以添加
CREATE TABLE IF NOT EXISTS

这会阻止它重新创建表,但每次调用oncreate似乎仍不太对。


好问题,希望有人能提供答案。至于你的“插入”,在关闭数据库之前,你是否标记了事务成功? - Dave G
将你的类声明为静态的能解决这个问题吗? - Ben Williams
@DAVE G 所有数据肯定会进入数据库,我是不是需要在插入后关闭数据库?目前只是这样做:SQLiteDatabase db = this.getWritableDatabase(); ...收集所有数据并执行:db.insert("TABLENAME", null, cv);... 然后就结束了?! - Bex
@Ben 谢谢回复.. 但我不能将它声明为静态的,因为它不允许我这样做! - Bex
你能给我们提供你的辅助工具的完整源代码吗?这个方法看起来不像是有问题的那一个 ;) - darune
@Darune 谢谢您的回复!我很确定它不是有问题的那个..但我不确定在哪里需要初始化这个类,因为每次调用其中的方法时,我都会重新初始化这个类!我认为我只需要知道在哪里初始化这个类,因为我做得太频繁了。 - Bex
4个回答

2
你可以在它周围放置一个包装类吗?
public class DbAdapter
{

  // database details
  private static final String DATABASE_NAME = "dbname";
  private static final int DATABASE_VERSION = 1;

  // where we're running
  private final Context mCtx;

  private static class DatabaseHelper extends SQLiteOpenHelper
  {
    DatabaseHelper(Context context)
    {
      super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db)
    {
      // your initial database create statements go here
      db.execSQL(DATABASE_CREATE);
    }

    // if you need to recreate the database, you just up the version number
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
      // drop commands for each table goes here
      db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
      onCreate(db);
    }
  }

  public DbAdapter(Context ctx)
  {
    this.mCtx = ctx;
  }

  public DbAdapter open() throws SQLException
  {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
  }

  public void close()
  {
    mDbHelper.close();
  }

  // other database methods can go here
}

1

onCreate() 方法只在第一次尝试访问数据库且未创建时调用。因此,onCreate() 只会被调用一次。getWritableDatabase 返回一个 db 对象,并在需要时调用 onCreate()NotePadProvider 提供了一个很好的示例,说明如何使用 SQLiteOpenHelper


当您说第一次访问数据库时,是指永远还是在当前“会话”期间? - Bex
记事本示例应用程序的链接已经失效了。有任何想法它被移动到哪里了吗? - syonip
为了让onCreate()再次被调用,我不能卸载应用程序吗?当我重新安装应用程序时,似乎会使onCreate()再次被调用。只是补充一下@MojoRisin所说的“永远”。 - Michael Osofsky

0

我不确定你所说的这个语句的意思 -

"每个活动我都重新初始化类,以便我可以访问类中的函数。"

在需要访问数据库的每个活动中,您只需打开数据库,访问/更新表中的数据,然后关闭处理程序即可。

您看过这个简单的NotePad应用程序示例吗 -

Google的NotePad示例应用程序

也许那会有所帮助。


0

数据库初始化代码应该放在您的 Helper 的 onCreate 方法中。 来自 Android SQLiteOpenHelper javadocs:

/**
 * Called when the database is created for the first time. This is where the
 * creation of tables and the initial population of the tables should happen.
 *
 * @param db The database.
 */
public abstract void onCreate(SQLiteDatabase db);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接