SQLiteOpenHelper Sync

So, I came up with some idea, and I wonder if this is possible.

Let's say I have several tables (database models), each of which is represented by a certain class. I do not want to use a singleton open-helper template, so I created a simple class to provide a single database instance. My idea is that as long as all tables contain a reference to SQLiteDatabase (returned by the open helper), they will all work with the same DB instance and probably will not be needed to synchronize work with the database, since the open helper is . When the last table finishes, GC will assemble an open helper (since the last link will be a weak link) -> finalize () is called, and I close db during this method to prevent any warning from the OS. My question is: can this work? Will it automatically close the database and will it leak or throw an exception?

Here is my 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(); } } } 
+8
android synchronization weak-references sqliteopenhelper
source share
5 answers

Actually did not know the answer, but was interested and looked for it.

The answer here is spelled correctly; http://blog.foxxtrot.net/2009/01/a-sqliteopenhelper-is-not-a-sqlitetablehelper.html

But basically a core of information;

I created three SQLiteOpenHelper classes, one for each table, although they all referred to only one database file.

Everything fell apart here. Android supports database versions based on the package associated with it, the name of the database, and the version number that you provide. The package and name indicate what the path will be on the device, and the version is stored (somewhere) on the device so that it knows when it needs to call the OpenHelpers onUpgrade event handler. It turns out that if it determines in the SQLiteOpenHelper constructor that the database already exists, it will not call the onCreate or onUpgrade methods at all, even if the previously called class has never been called.

+2
source share

I had the same problem when I was working on a project. I also went crazy with doubts that the static instance was using enough memory and causing a significant memory leak.

I'm not sure that creating a weak link ensures that the database instance is built. However, a possible workaround might be: Assigning a null value to a static database instance after completing the entire database transaction and closing the database. This can ensure that the database instance no longer allocates any memory.

Let me know if this works, or if there is more efficient work.

+2
source share

You can do it. As you say, the lock should happen on SQLite, and I never heard about it, so everything should be fine with this. The only limitation you have is that all tables will have to go to the same database, since Android now just allows you to have one file.

Closing a database is a completely different matter, so it’s actually interesting to use the singleton pattern (you avoid closing + opening all the time). However, with your approach, you just need to close db when you are done with it. As far as I know, this is not done automatically.

In addition, Lars Vogel has written extremely useful and detailed articles on database access in Android. You might want to look there. http://www.vogella.com/articles/AndroidSQLite/article.html

+1
source share

you can use one open helper for the whole table. I also use one instance in my application.

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

My question is: can this work? Will it automatically close the database and will it leak or throw some kind of exception?

NO, it will not automatically close the database when your application requires DATABASE for the object, and the OS has detected that some of your instant data in the database is alive, then the Android infrastructure is trying to associate this link with the object (which is probably is a weak standard)

and I have to say that I do not recommend opening and closing the database on demand or temporarily. It is always a pleasure to open a database ahead of schedule and keep it open throughout your activity and close it when the activity is completed or suspended.

0
source share

All Articles