首页 > 解决方案 > 更新应用程序崩溃 RealMigrationNeededException 但尚未修改 RealmObjects

问题描述

我最近发布了我的应用程序的新版本,更新到它后,由于“io.realm.exceptions.RealmMigrationNeededException:由于以下错误需要迁移”,应用程序立即崩溃

我的目标是更新应用程序,运行领域迁移而不会崩溃。

应用程序因 io.realm.exceptions.RealmMigrationNeededException 崩溃:由于以下错误需要迁移:

Property 'HistoryLogModel.bytes' has been made optional. (unmodified for this release)

Property 'StatusDataModel.data' has been made optional. (unmodified for this release)

Property 'TelemetryLogModel.data' has been made optional. (unmodified for this release)

Property 'TelemetryLogModel.timeStamp' has been made optional. (modified for this release and migration is created)

除了 TelemetryLogModel.timeStamp 之外,其余这些属性都未针对此版本进行修改。

该应用程序的原始版本具有io.realm:realm-gradle-plugin:7.0.2

最新版本有io.realm:realm-gradle-plugin:7.0.8

查看更新日志,这两个版本之间没有重大更改。

这是堆栈跟踪:

--------- beginning of crash
03-25 11:21:45.649  1830  1830 E AndroidRuntime: FATAL EXCEPTION: main
03-25 11:21:45.649  1830  1830 E AndroidRuntime: Process: com.nicolbolas.magic, PID: 1830
03-25 11:21:45.649  1830  1830 E AndroidRuntime: java.lang.RuntimeException: Unable to create application com.nicolbolas.magic.ProtectedApp: com.nicolbolas.magic.MessageGuardException_TWlncmF0aW9uIGlzIHJlcXVpcmVkIGR1ZSB0byB0aGUgZm9sbG93aW5nIGVycm9yczoKLSBQcm9wZXJ0eSAnSGlzdG9yeUxvZ01vZGVsLmJ5dGVzJyBoYXMgYmVlbiBtYWRlIG9wdGlvbmFsLgotIFByb3BlcnR5ICdTdGF0dXNEYXRhTW9kZWwuZGF0YScgaGFzIGJlZW4gbWFkZSBvcHRpb25hbC4KLSBQcm9wZXJ0eSAnVGVsZW1ldHJ5TG9nTW9kZWwuZGF0YScgaGFzIGJlZW4gbWFkZSBvcHRpb25hbC4KLSBQcm9wZXJ0eSAnVGVsZW1ldHJ5TG9nTW9kZWwudGltZVN0YW1wJyBoYXMgYmVlbiBtYWRlIG9wdGlvbmFsLg: Migration is required due to the following errors:
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'HistoryLogModel.bytes' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'StatusDataModel.data' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'TelemetryLogModel.data' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'TelemetryLogModel.timeStamp' has been made optional. (RmluZ2VycHJpbnQgMjAyMDA2MjkgWysuLisuLl0gYXJtNjQtdjhhOmFybTY0LXY4YSAzMC8yLjEuMC8tIGdvb2dsZS9ibHVlbGluZS9ibHVlbGluZToxMS9SUTJBLjIxMDMwNS4wMDYvNzExOTc0MTp1c2VyL3JlbGVhc2Uta2V5cw==)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6720)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.app.ActivityThread.access$1300(ActivityThread.java:237)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:106)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:223)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:7660)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.android.internal.os.Device.fp(RmluZ2VycHJpbnQgMjAyMDA2MjkgWysuLisuLl0gYXJtNjQtdjhhOmFybTY0LXY4YSAzMC8yLjEuMC8tIGdvb2dsZS9ibHVlbGluZS9ibHVlbGluZToxMS9SUTJBLjIxMDMwNS4wMDYvNzExOTc0MTp1c2VyL3JlbGVhc2Uta2V5cw==:0)
03-25 11:21:45.649  1830  1830 E AndroidRuntime: Caused by: com.nicolbolas.magic.MessageGuardException_TWlncmF0aW9uIGlzIHJlcXVpcmVkIGR1ZSB0byB0aGUgZm9sbG93aW5nIGVycm9yczoKLSBQcm9wZXJ0eSAnSGlzdG9yeUxvZ01vZGVsLmJ5dGVzJyBoYXMgYmVlbiBtYWRlIG9wdGlvbmFsLgotIFByb3BlcnR5ICdTdGF0dXNEYXRhTW9kZWwuZGF0YScgaGFzIGJlZW4gbWFkZSBvcHRpb25hbC4KLSBQcm9wZXJ0eSAnVGVsZW1ldHJ5TG9nTW9kZWwuZGF0YScgaGFzIGJlZW4gbWFkZSBvcHRpb25hbC4KLSBQcm9wZXJ0eSAnVGVsZW1ldHJ5TG9nTW9kZWwudGltZVN0YW1wJyBoYXMgYmVlbiBtYWRlIG9wdGlvbmFsLg: Migration is required due to the following errors:
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'HistoryLogModel.bytes' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'StatusDataModel.data' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'TelemetryLogModel.data' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'TelemetryLogModel.timeStamp' has been made optional. (RmluZ2VycHJpbnQgMjAyMDA2MjkgWysuLisuLl0gYXJtNjQtdjhhOmFybTY0LXY4YSAzMC8yLjEuMC8tIGdvb2dsZS9ibHVlbGluZS9ibHVlbGluZToxMS9SUTJBLjIxMDMwNS4wMDYvNzExOTc0MTp1c2VyL3JlbGVhc2Uta2V5cw==)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.ProtectedApp.onCreate(Unknown Source:169)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1192)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6715)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    ... 9 more
03-25 11:21:45.649  1830  1830 E AndroidRuntime: Caused by: io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'HistoryLogModel.bytes' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'StatusDataModel.data' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'TelemetryLogModel.data' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime: - Property 'TelemetryLogModel.timeStamp' has been made optional.
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:175)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:251)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.BaseRealm.<init>(BaseRealm.java:137)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.BaseRealm.<init>(BaseRealm.java:104)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.Realm.<init>(Realm.java:163)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.Realm.createInstance(Realm.java:499)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.RealmCache.createInstance(RealmCache.java:507)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:473)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:414)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at io.realm.Realm.getInstance(Realm.java:428)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.repo.RealmRepository.initialize(RealmRepository.kt:132)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.components.TKG.restoreRepo(TKG.kt:57)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.components.AppComponentStore.<init>(AppComponentStore.kt:176)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.App.initializeComponentStore(App.kt:327)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.App.initializeSecondaryComponents(App.kt:238)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.App.setup(App.kt:218)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.App.onCreate(App.kt:189)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.ProtectedApp.ajcmiqvwAG(Native Method)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.ProtectedApp$R$font.jorgkwmf(Unknown Source:653)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.ProtectedApp$R$font.eDnHas(Unknown Source:99)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.ProtectedApp$R$font.wpHrAw(Unknown Source:147)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    at com.nicolbolas.magic.ProtectedApp.onCreate(Unknown Source:117)
03-25 11:21:45.649  1830  1830 E AndroidRuntime:    ... 11 more

领域迁移文件:

class MagicRealmMigrations: RealmMigration {

    override fun hashCode(): Int {
        return MagicRealmMigrations::javaClass.hashCode()
    } 

    override fun equals(other: Any?): Boolean {
        if (null == other) {
            return false
        }
        return other is MagicRealmMigrations
    }

    override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
        val schema = realm.schema
        var localOldVersion = oldVersion

        if (localOldVersion < 1L) {
            val profileSettingsSchema = schema.get("ProfileSettings")
            profileSettingsSchema?.addField("hasUploaded", Boolean::class.java)
            localOldVersion++
        }

        if (localOldVersion == 1L) {
            val telemetryLogSchema = schema.get("TelemetryLogModel")
            telemetryLogSchema?.removePrimaryKey()
            localOldVersion++
        }

        if(localOldVersion == 2L) {
            val telemetryLogSchema = schema.get("TelemetryLogModel")
            telemetryLogSchema?.addField("id", Long::class.java)

            val telemetryLogs = realm.where("TelemetryLogModel")
                .sort("timeStampSeconds", Sort.ASCENDING)
                .findAll()
            for((counter, log) in telemetryLogs.withIndex()) {
                    log.set("id", counter)
            }

            telemetryLogSchema?.addPrimaryKey("id")
            localOldVersion++
        }
    }
}

领域对象:

open class StatusDataModel(@PrimaryKey open var id: Long = 0,
var statusDataType: Int = 0,
var data: String = "",
var timeUTCMillis: Long = 0) : RealmObject()

open class TelemetryLogModel(@PrimaryKey var id: Long = 0,
var data: String = "",
var timeStampSeconds: Long = 0,
var timeStamp: String = "",
var uploaded: Boolean = false,
var code: Int = 0): RealmObject()

open class HistoryLogModel(@PrimaryKey open var sequenceNumber: Long = 0,
open var bytes: ByteArray = ByteArray(0),
open var typeId: Int = 0,
open var pumpTimeSeconds: Long = 0) : RealmObject()

实例化领域

private var realmSchemaVersion = 3L
Log.d(TAG, "Database accessed from default location.")
val config = RealmConfiguration.Builder()
            .schemaVersion(realmSchemaVersion)
            .migration(MagicRealmMigrations())
            .also {
                k?.let { key ->
                    it.encryptionKey(key)
                   }
            }
            .build()
this.config = config
Realm.getInstance(config)

重现的步骤和代码

一旦我从一个版本更新到另一个版本,崩溃就会立即发生。

Realm 和工具的版本

领域版本:io.realm:realm-gradle-plugin:7.0.8

启用领域同步功能:否

安卓工作室版本:4.1.3

Android 构建工具版本:29.0.2

摇篮版本:4.0.0

哪个 Android 版本和设备:

三星盖乐世 S9 安卓 11

谷歌像素 3 安卓 11

标签: androidrealmrealm-mobile-platformrealm-migrationrealm-java

解决方案


推荐阅读