【问题标题】:Firebase Database crash SQLiteDatabaseLockedExceptionFirebase 数据库崩溃 SQLiteDatabaseLockedException
【发布时间】:2017-08-12 07:11:37
【问题描述】:

我在少数设备上遇到此崩溃,但仅在 Android 4 上。

我使用的是 Firebase Android SDK 10.2.1 11.0.2。推迟更新到最新版本,因为它也会强制更新 Google Play 服务,而且许多用户继续使用较旧的 GPS 版本。

还有其他人看到这个问题吗?

更新:这在早期工作。在我从 Firebase SDK 9.4.0 升级到 10.2.1 并将 compileSdkVersion 23 升级到 25 后开始崩溃。崩溃仅发生在 Android 4.4 (Kitkat 19) 上

更新例外:

Fatal Exception: java.lang.RuntimeException
       at com.google.android.gms.internal.mz.run(Unknown Source)
       at android.os.Handler.handleCallback(Handler.java:808)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loop(Looper.java:193)
       at android.app.ActivityThread.main(ActivityThread.java:5292)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by o.kD: Failed to gain exclusive lock to Firebase Database's offline persistence. This generally means you are using Firebase Database from multiple processes in your app. Keep in mind that multi-process Android apps execute the code in your Application class in all processes, so you may need to avoid initializing FirebaseDatabase in your Application class. If you are intentionally using Firebase Database from multiple processes, you can only enable offline persistence (i.e. call setPersistenceEnabled(true)) in one of them.
       at com.google.android.gms.internal.nb.zzN(Unknown Source)
       at com.google.android.gms.internal.nb.(Unknown Source)
       at com.google.android.gms.internal.mx.zza(Unknown Source)
       at com.google.android.gms.internal.qd.zzgQ(Unknown Source)
       at com.google.android.gms.internal.qu.zzHg(Unknown Source)
       at com.google.android.gms.internal.qu.zza(Unknown Source)
       at com.google.android.gms.internal.qv.run(Unknown Source)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:841)
Caused by android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: PRAGMA journal_mode
       at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java)
       at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:893)
       at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:638)
       at android.database.sqlite.SQLiteConnection.setJournalMode(SQLiteConnection.java:320)
       at android.database.sqlite.SQLiteConnection.setWalModeFromConfiguration(SQLiteConnection.java:294)
       at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:215)
       at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
       at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
       at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
       at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
       at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:829)
       at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:814)
       at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:709)
       at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1039)
       at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:256)
       at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
       at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
       at com.google.android.gms.internal.nb.zzN(Unknown Source)
       at com.google.android.gms.internal.nb.(Unknown Source)
       at com.google.android.gms.internal.mx.zza(Unknown Source)
       at com.google.android.gms.internal.qd.zzgQ(Unknown Source)
       at com.google.android.gms.internal.qu.zzHg(Unknown Source)
       at com.google.android.gms.internal.qu.zza(Unknown Source)
       at com.google.android.gms.internal.qv.run(Unknown Source)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:841)

我在应用程序中确实有多个进程,但使用以下代码为子进程中止 Application.onCreate。

@Override
public void onCreate() {
    super.onCreate();

    if (FirebaseApp.getApps(this).isEmpty()) {
        // No firebase apps; we are in a non-main process
        return;
    }

    // Firebase init and other custom logic
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}

【问题讨论】:

  • 启用multidex
  • @IntelliJAmiya 你能解释一下为什么 multidex 是这里的问题吗?这次崩溃对我来说是不可重复的,我唯一的选择是在生产环境中进行测试。
  • @NizamMohideen 即使我也面临同样的问题。你有没有找到任何解决方案。

标签: android firebase firebase-realtime-database


【解决方案1】:

Firebase 中没有 SQLiteDatabaseLockedException。当您在 Android 中使用 SQLite 数据库并且数据库引擎无法获取需要完成其工作的数据库锁时,会抛出此 SQLiteDatabaseLockedException

如果语句是 [COMMIT] 或出现在显式事务之外,那么您可以重试该语句。如果语句不是 [COMMIT] 并且发生在显式事务中,那么您应该在继续之前回滚事务。

编辑:通过对详细堆栈跟踪的新编辑,我知道错误是什么。设置setPersistenceEnabled(true) 时发生错误。这必须在对您的 firebaseDatabase 对象执行任何其他操作之前完成。因此,我建议您使用以下代码:

public class HelperClass {
    private static FirebaseDatabase firebaseDatabase;
    public static FirebaseDatabase getDatabase() {
        if (firebaseDatabase == null) {
            firebaseDatabase = FirebaseDatabase.getInstance();
            firebaseDatabase.setPersistenceEnabled(true);
        }
        return firebaseDatabase;
    }
}

【讨论】:

  • 崩溃确实来自 Firebase 数据库。在我的问题中更新了更详细的堆栈跟踪。
  • 现在我知道这是一个已确认的 Firebase 数据库问题,我有更多线索。这是一段工作代码,在我从 Firebase SDK 9.4.0 升级到 10.2.1 后崩溃开始了。将 Firebase 升级到 11.0.2 后,崩溃仍在继续。 Google Play 服务现在也是 11.0.2。
  • 我有一个单例 FirebaseManager,我首先要做的是 setPersistenceEnabled,所以这可能不是问题。无论如何,这是早些时候工作的,所以不要怀疑代码。
猜你喜欢
  • 2017-03-26
  • 2019-03-23
  • 2017-05-15
  • 2016-09-18
  • 2018-12-16
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多