Проблема с API 28 в том, что WAL (запись в очередь записи) включена по умолчанию.Если, как это часто бывает, база данных открыта, что часто делается при проверке наличия базы данных, то создаются два файла: -wal и -shm.
Например, в вашем коде это означает, что вы делаете следующее: -
// Path to the just created empty db
String outFileName = getDbPath() + mDbName;
Когда существующая база данных переопределяется копией, файлы -wal и -shmостаются.
Когда в конце концов попытается открыть базу данных как базу данных SQLiteD, возникает несоответствие между базой данных и файлами -wal и -shm.Затем базовое открытие SQLiteDatabase решает, что база данных не может быть открыта, и, таким образом, чтобы обеспечить пригодную для использования базу данных, удаляет и воссоздает базу данных, эффективно опустошая базу данных, и, следовательно, возникает ситуация.1010 *
- Переопределите метод onConfigure и заставьте его использовать старый режим журнала (используя [disableWriteAheadLogging] (метод https://developer.android.com/reference/android/arch/persistence/db/SupportSQLiteDatabase#disablewriteaheadlogging)).
- Используйте метод открытия SQLiteDatabase, чтобы проверить, существует ли база данных, но проверить, существует ли файл.
- В качестве части копии удалите файлы -wal и -shm.
Я бы предположил, что 2 или 3 являются лучшими способами, как: -
- Нет никаких накладных расходов на ненужное открытие (и создание) базы данных, просто чтобы проверитьего существование и создание каталогов.
- Приложение, вероятно, будет улучшено благодаря преимуществам WAL по сравнению с ведением журнала.
Все вышеперечисленное Приложение для Android с предварительно заполненной базой данных .
Код решения фактически включает в себя как 2, так и 3 (хотя исправление 3 не требуется) (поскольку исправление 2 не открывает базу данных как базу данных SQLite)).
Сказав, что я считаю, чтоследующий код для проверки, существует ли база данных (исправление 2), лучше ее эквивалента в ответе выше: -
/**
* Check if the database already exists. NOTE will create the databases folder is it doesn't exist
* @return true if it exists, false if it doesn't
*/
public static boolean checkDataBase(Context context, String dbname) {
File db = new File(context.getDatabasePath(dbname).getPath()); //Get the file name of the database
Log.d("DBPATH","DB Path is " + db.getPath()); //TODO remove if publish App
if (db.exists()) return true; // If it exists then return doing nothing
// Get the parent (directory in which the database file would be)
File dbdir = db.getParentFile();
// If the directory does not exits then make the directory (and higher level directories)
if (!dbdir.exists()) {
db.getParentFile().mkdirs();
dbdir.mkdirs();
}
return false;
}