Exported SQLite database is not up to date
Asked Answered
D

1

5

This issue only applies to an SDK 28 device (emulator). My SQLite database created with SQLiteOpenHelper works perfectly in the app, however when I export it to a disk (either by means of Android studio or by the code), much of its data is lost. Changes made to this database in the app are immediately reflected in the app but are not reflected in the exported database file. The database file that I am trying to export is located here: DDMS -> file explorer -> data -> data -> my package name -> databases -> my database file. On an SDK < 28 device, the database file is exported perfectly well.

Downwash answered 18/12, 2018 at 13:41 Comment(7)
B001ᛦ, that answer there says: Go to DDMS -> file explorer -> data -> data -> see your package name -> databases -> here your database file. I am talking exactly about this location. When I export my database from this location, its data is lost. Please read my problem description once again. The topic you provided does not resolve my problem.Downwash
How are you exporting the database?Autodidact
Shawn, I do this in two ways: manually and by the code. Manually: open the Device Explorer in the Android Studio. Then expand folders to find the database file: data -> data -> package of my app -> databases -> my database file. Then right-click on the file name and then "Save as..." The second way is by the code: link Both ways give the same result - a database file with incomplete data.Downwash
If there's any open connections to the database, just copying the file is a great way to get data loss or with bad timing, an unreadable corrupt database. If the sqlite binding you're using provides the backup api use that, otherwise gracefully shut down all open connections to the file before copying it.Autodidact
Shawn, how can I close the connections? I use ContentProvider for accessing the database, and everybody says that closing connections can result in crashes. Maybe this happens because I use CursorLoader that became deprecated in SDK 28?Downwash
Doing whatever is needed to call the underlying C sqlite3_finalize() function on any prepared statements and sqlite3_close() or sqlite3_close_v2() on any database handles that use that file. I have no idea what that involves on your environment. If there are no current connections but the prior ones weren't shut down cleanly, opening and immediately closing a connection will clean up any lingering journal files etc.Autodidact
Sham, I resolved the issue and provided the description in the answer entry.Downwash
D
9

I resolved the issue independently.

I found that the database folder in addition to the database itself contains two supplementary files. The contents of the folder looked like this:

  • MyDatabase.db
  • MyDatabase.db-shm
  • MyDatabase.db-wal

Without these files, the database is incomplete.

Prior to the SDK 28, there is only one supplementary file and it does not impact the integrity of the database:

  • MyDatabase.db-journal

The solution was to execute .setWriteAheadLoggingEnabled(false) on the singleton instance of my database in SQLiteOpenHelper:

synchronized static MyDatabase getInstance(Context context) {
    if (instance == null) {
        instance = new MyDatabase(context.getApplicationContext());
        instance.setWriteAheadLoggingEnabled(false);
    }
    return (instance);
}

This restores the database logging setting used in the SDKs < 28 by default. Doing this provides me with a single database file that contains the full and up to date data not depending on supplementary files.

Downwash answered 19/12, 2018 at 11:46 Comment(2)
Have you seen any downsides to using setWriteAheadLoggingEnabled?Upwards
I have not noticed any changes in app behavior compared to what was before using setWriteAheadLoggingEnabled. So no downsides noticed. Though you may consider the functionality where it is used too simple. You can check it in the "Manage data" section of this app: play.google.com/store/apps/…Downwash

© 2022 - 2024 — McMap. All rights reserved.