views:

42

answers:

1

This Android application on Google uses the following method to refresh the database after replacing the database file with a backup:

public void resetDbConnection() { 
    this.cleanup(); 
    this.db = 
        SQLiteDatabase.openDatabase(
           "/data/data/com.totsp.bookworm/databases/bookworm.db",
            null, SQLiteDatabase.OPEN_READWRITE); 
} 

I did not build this app, and I am not sure what happens. I am trying to make this idea work in my own application, but the data appears to be cached by the views, and the app continues to show data from the database that was replaced, even after I call cleanup() and reopen the database. I have to terminate and restart the activity in order to see the new data.

I tried to call invalidate on my TabHost view, which pretty much contains everything. I thought that the views would redraw and refresh their underlying data, but this did also not have the expected result.

I ended up restarting the activity programmatically, which works, but this seems to be a drastic measure. Is there a better way?

+1  A: 

Agreed with Pentium10, at least conceptually.

The application is using a Cursor to show its data. A Cursor in Android is akin to a client-side cursor in ODBC, in that it is a cached copy of all of the data represented by the query's result set.

Now, the normal way of handling changes in the database contents is to call requery() on the Cursor. That will ripple its changes through the CursorAdapter to attached ListViews or other AdapterViews.

In your case, I am not completely certain that will work, since you are closing, replacing, and re-opening the database. That should not be done with an open Cursor on the data, AFAIK. So, in your case, you'd need to close the Cursor, do the database shuffle, then run the query again to get a fresh Cursor on your new database.

CommonsWare
This seems impractical, since I have a TabHost with multiple tabs that each has its own cursor open. I am not even sure how I would notify each Tab's cursor to do a requery(). What actually seems to happen is that the cursors refresh themselves when they detect the change. For instance, when I initiate an event to one of my ListViews that results in an attempt to update a row that no longer exists in the database, the cursor refreshes and the ListView shows the correct data. I am not saying that this is how I want it to behave, I just mention this as an observation.
cdonner
@cdonner: "What actually seems to happen is that the cursors refresh themselves when they detect the change." If they are managed cursors, that is eminently possible. It is still rather unlikely that they will appreciate having their database ripped out from under them. Perhaps you can restore your database only when the application is starting up, or some other time when you know you will have no open database connections.
CommonsWare
Waiting for the user to do something with the data and then showing him something else is not acceptable, of course. I'll keep my code that finishes the activity and restarts it, since it ensures that everything is re-initialized properly.
cdonner