android - Firebase 数据库崩溃 SQLiteDatabaseLockedException

标签 android firebase firebase-realtime-database

我在少数设备上遇到此崩溃,但仅限于 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);
}

最佳答案

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

If the statement is a [COMMIT] or occurs outside of an explicit transaction, then you can retry the statement. If the statement is not a [COMMIT] and occurs within a explicit transaction then you should rollback the transaction before continuing.

编辑:通过对详细堆栈跟踪的新编辑,我明白了错误是什么。当您设置 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;
    }
}

关于android - Firebase 数据库崩溃 SQLiteDatabaseLockedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45647578/

相关文章:

android - 将 key 存储在 .properties 文件中是不好的做法吗

android - 如何在 android 中从 json 动态创建可扩展 ListView 中的组和子项?

android - 从用户的声音中获取振幅

Android TextView 改变 textColor 与主题

android - 听视频广告。插页式广告中的完成事件 (Google AdMob)

java - 检查 Firebase 数据库中是否存在特定值

ios - 在 UITableView 中显示 Firebase 数据

android - 电子邮件不存在时 Firebase 重置密码

javascript - ngIf 不评估异步代码 Angular 和 Firebase

android - 由于 Firebase 规则不是过滤器,那么我们如何过滤呢?