SQLiteOpenHelper同步

所以我想出了一些想法,我想知道它是否可以实现。

比方说,我有多个表(数据库模型),每个表都由一些类来表示。我不会用开放的帮助器来使用单例模式,所以我创build了一些简单的类来提供单个数据库实例。我的的想法是,只要所有的表持有对SQLiteDatabase的引用(由开放的帮助器返回),他们都将使用相同的数据库实例,可能不需要同步工作与数据库,因为打开帮助器这样做。最后一个表完成它的工作GC将收集打开帮助(因为最后一个引用将是弱引用) – >调用finalize(),并在此方法中closures数据库,以防止从操作系统的任何警告。 我的问题是:这是否可以工作?它会自动closures数据库,将泄漏或抛出一些exception?

这是我的class级:

public class DatabaseHelper { private static WeakReference<SomeCustomOpenHelper> sDBOpenHelper; private void notifyDBCreate(SQLiteDatabase db) { for (DBTable table : mTables) { table.onDBCreate(db); } } private void notifyDBUpgrade(SQLiteDatabase db) { for (DBTable table : mTables) { table.onDBUpgrade(db); } } public SQLiteDatabase getDatabase(boolean readOnly) { SomeCustomOpenHelper dbHelper = sDBOpenHelper.get(); if (dbHelper == null) { dbHelper = new SomeCustomOpenHelper(context, name, factory, version, new DatabaseEventsCallback()); sDBOpenHelper = new WeakReference<SomeCustomOpenHelper>(dbHelper); } if (readOnly) { return dbHelper.getReadableDatabase(); } else { return dbHelper.getWritableDatabase(); } } private class DatabaseEventsCallback implements IDatabaseEventsCallback { @Override public void onCreate(SQLiteDatabase db) { notifyDBCreate(db); } @Override public void onUpgrade(SQLiteDatabase db) { notifyDBUpgrade(db); } } interface IDatabaseEventsCallback { void onCreate(SQLiteDatabase db); void onUpgrade(SQLiteDatabase db); } private static class SomeCustomOpenHelper extends SQLiteOpenHelper { private IDatabaseEventsCallback mCB; public SomeCustomOpenHelper(Context context, String name, CursorFactory factory, int version, IDatabaseEventsCallback cb) { super(context, name, factory, version); mCB = cb; } @Override public void onCreate(SQLiteDatabase db) { mCB.onCreate(db); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { mCB.onUpgrade(db); } @Override protected void finalize() throws Throwable { this.close(); super.finalize(); } } } 

Solutions Collecting From Web of "SQLiteOpenHelper同步"

没有真正知道答案,但有兴趣,并查找它。

答案在这里写得正确。 http://blog.foxxtrot.net/2009/01/a-sqliteopenhelper-is-not-a-sqlitetablehelper.html

但基本上信息的核心是;

我创build了三个SQLiteOpenHelper类,每个表对应一个,尽pipe它们都只引用一个数据库文件。

这里是一切崩溃的地方。 Android根据与其关联的包,数据库的名称以及您提供的版本号来维护数据库的版本。 软件包和名称决定了设备上的path,而版本存储在设备上(某处),以便知道何时需要调用OpenHelper的onUpgrade事件处理程序。 事实certificate,如果在SQLiteOpenHelper构造函数中,它确定数据库已经存在,它将不会调用你的onCreate或onUpgrade方法,即使调用的特定类从未被调用过。

我在做一个项目的时候,也经历过同样的问题。 如果静态实例使用了足够的内存并造成相当大的内存泄漏,我也怀疑这个问题。

我不确定是否创build一个弱引用将保证数据库实例将被收集。 但是,可能的解决方法可能是:一旦完成所有数据库事务并将数据库closures,则为静态数据库实例分配一个空值。 这可能确保数据库实例不再分配任何内存。

让我知道这是否有效,或者是否有更好的解决方法。

你可以这样做。 正如你所说的locking应该发生在SQLite上,我从来没有听说过这个问题,所以你应该罚款。 唯一的限制是所有的表都必须进入同一个数据库,因为Android现在只允许你有一个文件。

closures数据库是不同的事情,这就是为什么使用单例模式(避免closures+始终打开)真正有趣的原因。 尽pipe如此,你只需要确保在你完成数据库时closures数据库。 就我而言,这不是自动完成的。

此外,Lars Vogel已经写出了非常有用和详细的文章围绕Android的数据库访问。 你可能想看看那里。 http://www.vogella.com/articles/AndroidSQLite/article.html

你可以使用一个开放的助手的所有表。我在我的应用程序中使用单个实例也是这样的。

 public static synchronized DatabaseHelper getInstance(Context ctx) { if (dbhelper == null) { dbhelper = new DatabaseHelper(ctx); } return dbhelper ; } 

我的问题是:这是否可以工作?它会自动closures数据库,将泄漏或抛出一些exception?

不,它不会自动closures数据库,当你的应用程序将要求DATABASE对象和操作系统发现你的一些数据库瞬间是活着的然后Android框架尝试连接该对象的引用(这可能是弱引用)

我不得不说,我不build议打开和closures数据库按需或临时。 提前打开数据库并在整个活动期间保持打开状态并在活动完成或暂停时closures数据库总是很好的。