You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用替换SQLite数据库后写入崩溃,重启恢复正常求助

Fixing SQLite Read-Only Crash After Database Update on Android

Let's break down what's happening here and walk through how to fix this crash:

What's Causing the Crash?

Your database update workflow has a critical gap: you aren't fully closing all active SQLite database connections before deleting the old database file. When you delete the old DB and copy the new one over, leftover connections (from either your own code or third-party libraries like Firebase Crash Reporting—you can see this in your logs) are still tied to the deleted file. When these connections try to write to the database, they hit a SQLiteReadOnlyDatabaseException because the original file no longer exists, triggering the immediate crash. Restarting works because all connections get reinitialized to the new, valid database file.

Looking at your LogCat, the crashes originate from Firebase's background threads attempting to write crash reports—this confirms a third-party library is holding an open connection to the old database you deleted.

Step-by-Step Fixes

1. Close All Database Connections First

Before touching any database files, ensure every SQLiteOpenHelper and SQLiteDatabase instance in your app is closed. If you use multi-threaded database access, add synchronization to guarantee no connections are left open:

// Close your app's SQLiteOpenHelper instance
if (myDbHelper != null) {
    myDbHelper.close();
    myDbHelper = null;
}

// Close any direct SQLiteDatabase references
if (myDatabase != null && myDatabase.isOpen()) {
    myDatabase.close();
    myDatabase = null;
}

2. Refine Your Database Replacement Workflow

Make your file operations atomic and enforce correct file permissions (Android requires database files to have 0600 permissions):

String dbName = "your_database_name.db";
File dbFile = getDatabasePath(dbName);
File tempDbFile = new File(dbFile.getAbsolutePath() + ".tmp");

// 1. Copy new database from assets to a temporary file first
try (InputStream in = getAssets().open("new_" + dbName);
     OutputStream out = new FileOutputStream(tempDbFile)) {
    byte[] buffer = new byte[1024];
    int length;
    while ((length = in.read(buffer)) > 0) {
        out.write(buffer, 0, length);
    }
} catch (IOException e) {
    e.printStackTrace();
    // Handle file copy error gracefully
}

// 2. Run the connection-closing code from step 1 here

// 3. Delete the old database file
if (dbFile.exists()) {
    dbFile.delete();
}

// 4. Rename temporary file to the official database name
tempDbFile.renameTo(dbFile);

// 5. Set correct file permissions for Android
dbFile.setReadable(true, false);
dbFile.setWritable(true, false);

3. Handle Third-Party Library Connections

Since Firebase Crash Reporting is triggering the crash, temporarily disable crash collection during the database update to stop it from holding an open connection:

// Disable Firebase Crash collection before starting the update
FirebaseCrash.setCrashCollectionEnabled(false);

// Run your full database update workflow here
// (close connections, replace DB, restore saved data)

// Re-enable collection once the update is complete
FirebaseCrash.setCrashCollectionEnabled(true);

Note: If you're using the newer Firebase Crashlytics, use Crashlytics.getInstance().setCrashlyticsCollectionEnabled(false) instead.

4. Reinitialize Database Connections After Update

Once you've restored your saved data to the new database, reinitialize your SQLiteOpenHelper or SQLiteDatabase instance so your app uses the fresh connection going forward.

Verification

After implementing these fixes:

  • Test the database update flow to confirm no crash occurs
  • Verify all your saved data is correctly restored in the new database
  • Restart the app to ensure data persists and the app runs normally

内容的提问来源于stack exchange,提问作者Manuel Rodrigues

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:23:07