Its*_*wan 5 java sqlite android android-9.0-pie
以下是导入和导出SQLite数据库的工作方法。在除Android Pie外的所有android版本中,其工作情况都很好。当我尝试导入Android Pie时,它显示成功的Toast,但未还原数据库。谁能帮我解决Android Pie(API 28)问题。
private void importDB() {
try {
File sd = Environment.getExternalStorageDirectory();
File cur_db_pat = new File(this.getDatabasePath(DATABASE_NAME).getAbsolutePath());
if (sd.canWrite()) {
String backupDBPath = bac_dir_nam +"/" + DATABASE_NAME;
File currentDB = new File(sd, backupDBPath);
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(cur_db_pat).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getBaseContext(), cur_db_pat.toString(),
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
.show();
}
}
private void exportDB() {
try {
File sd = Environment.getExternalStorageDirectory();
File cur_db_pat = new File(this.getDatabasePath(DATABASE_NAME).getAbsolutePath());
if (sd.canWrite()) {
String backupDBPath = bac_dir_nam+"/" + DATABASE_NAME;
File backupDB = new File(sd, backupDBPath);
FileChannel src = new FileInputStream(cur_db_pat).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getBaseContext(), backupDB.toString(),
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG)
.show();
}
}
Run Code Online (Sandbox Code Playgroud)
我对文件系统没有太多经验。因此,举个例子会很有帮助。
在Android Pie +中,SQLite已更改为默认设置,以使用通常更有效的预写日志记录(WAL)代替日记模式。
因此,将有两个与数据库同名的文件,但后缀为-shm(共享内存文件)和-wal(预写日志),我认为它们的存在是导致此问题的原因。 SQLite使用的临时文件(请参阅2.2和2.3)
一种解决方法是使用SQliteDatabase disableWriteAheadLogging方法禁用预写日志记录,而先前的方法将像以前一样工作,但日志效率较低。
另一个解决方法是还原时删除这两个文件。为了避免潜在的损坏,必须在进行备份之前确保对数据库进行适当的检查。见PRAGMA检查站;
以下是还原时删除这两个文件的摘要(请注意,假定已使用足够的检查点进行了备份):
// Added for Android 9+ to delete shm and wal file if they exist
File dbshm = new File(dbfile.getPath() + "-shm");
File dbwal = new File(dbfile.getPath()+ "-wal");
if (dbshm.exists()) {
dbshm.delete();
}
if (dbwal.exists()) {
dbwal.delete();
}
Run Code Online (Sandbox Code Playgroud)
另一个解决方法是额外备份并随后还原-shm和-wal文件。
您可能还希望考虑在导入/还原时重命名原始文件,在复制新文件后检查新文件的潜在好处(例如,使用PRAGMA integrity_check;),如果结果表明没有问题,则删除重命名的原始文件,否则删除导入的文件并将原始文件重命名为其原始名称,表明导入失败。
在您的 Db WorkHelper 类中 ovverride onOpen() 方法并设置disableWriteAheadLogging然后调用 onOpen() 标准,如果 android sdk 28 版本,则确保旧版本保持旧模式。
@Override
public void onOpen(SQLiteDatabase database) {
super.onOpen(database);
if(Build.VERSION.SDK_INT >= 28)
{
database.disableWriteAheadLogging();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下 WORK 完美。
| 归档时间: |
|
| 查看次数: |
1423 次 |
| 最近记录: |