所以我想出了一些想法,我想知道它是否可以实现。
假设我有多个表(数据库模型),每个表都由某个类表示。我不习惯将单例模式与打开助手一起使用,所以我创建了一些简单的类来提供database.My的单个实例。我的想法是,只要所有的表都持有对SQLiteDatabase的引用(由打开助手返回),它们都将使用相同的DB实例,并且可能不需要与数据库同步工作,因为打开助手完成了最后一个表的工作,GC将收集打开助手的工作(因为最后一个引用将是弱引用)调用了-> finalize(),并且我在此方法期间关闭了db,以防止来自操作系统的任何警告。我的问题是:这可以工作吗?它会自动关闭数据库,它会泄漏或抛出一些异常吗?
下面是我的类:
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();
}
}
}发布于 2013-03-27 17:01:47
也不是真的知道答案,但感兴趣并查了查。
答案在这里写得很好;http://blog.foxxtrot.net/2009/01/a-sqliteopenhelper-is-not-a-sqlitetablehelper.html
但基本上信息的核心是;
我创建了三个 SQLiteOpenHelper 类,每个表一个,尽管它们都只引用了一个数据库文件。
这就是一切崩溃的地方。 Android 根据与之关联的包、数据库的名称和您提供的版本号来维护数据库的版本。 包和名称决定了设备上的路径,而版本存储在设备上(某处),以便它知道何时需要调用 OpenHelper 的 onUpgrade 事件处理程序。 事实证明,如果在 SQLiteOpenHelper 构造函数中,它确定数据库已经存在,它根本不会调用您的 onCreate 或 onUpgrade 方法,即使之前从未调用过进行调用的特定类。
发布于 2013-04-04 17:56:24
当我在一个项目中工作时,我也遇到过同样的问题。我还疯狂地怀疑静态实例是否使用了足够的内存,并导致了相当大的内存泄漏。
我不确定创建弱引用是否能保证数据库实例会被收集。然而,一种可能的解决方法可能是:在所有数据库事务完成并关闭数据库后,将空值分配给静态数据库实例。这可以确保数据库实例不再分配任何内存。
请让我知道这是否有效,或者是否有更好的解决办法。
发布于 2013-04-02 05:35:07
您可以这样做。正如您所说的,锁定应该发生在SQLite上,而我从来没有听说过这个问题,所以您应该可以接受这个问题。你唯一的限制是所有的表都必须放到同一个数据库中,因为Android现在只允许你有一个文件。
关闭数据库是另一回事,这就是为什么使用单例模式很有趣(避免总是关闭+打开)。尽管如此,使用您的方法时,您只需确保在使用完数据库时关闭它。就我而言,这不是自动完成的。
此外,Lars Vogel写了关于Android中DB访问的非常有用和详细的文章。你可能想去那里看看。http://www.vogella.com/articles/AndroidSQLite/article.html
https://stackoverflow.com/questions/15654745
复制相似问题