diff --git a/CHANGELOG.md b/CHANGELOG.md index dbcc12deba..4ea1b4fb83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,34 @@ +## 3.0.1 (YYYY-MM-DD) + +### Breaking Changes +* None. + +### Enhancements +* None. + +### Fixed +* Stopped using kotlin reflection, which caused ANR on some devices (Issue [#1544](https://github.com/realm/realm-kotlin/issues/1544)). + +### Compatibility +* File format: Generates Realms with file format v24 (reads and upgrades file format v10 or later). +* Realm Studio 15.0.0 or above is required to open Realms created by this version. +* This release is compatible with the following Kotlin releases: + * Kotlin 2.0.20 and above. Support for experimental K2-compilation with `kotlin.experimental.tryK2=true`. + * Ktor 2.1.2 and above. + * Coroutines 1.7.0 and above. + * AtomicFu 0.18.3 and above. + * The new memory model only. See https://github.com/realm/realm-kotlin#kotlin-memory-model-and-coroutine-compatibility +* Minimum Kbson 0.4.0. +* Minimum Gradle version: 7.2. +* Minimum Android Gradle Plugin version: 7.1.3. +* Minimum Android SDK: 16. +* Minimum R8: 8.0.34. + +### Internal +* None. + + ## 3.0.0 (2024-10-03) ### Breaking Changes diff --git a/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt b/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt index 97f948eafb..4fe2572197 100644 --- a/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt +++ b/packages/library-base/src/jvm/kotlin/io/realm/kotlin/internal/platform/RealmObject.kt @@ -19,15 +19,36 @@ package io.realm.kotlin.internal.platform import io.realm.kotlin.internal.RealmObjectCompanion import io.realm.kotlin.types.BaseRealmObject import kotlin.reflect.KClass -import kotlin.reflect.full.companionObjectInstance + // TODO OPTIMIZE Can we eliminate the reflective approach? Maybe by embedding the information // through the compiler plugin or something similar to the Native findAssociatedObject @PublishedApi -internal actual fun realmObjectCompanionOrNull(clazz: KClass): RealmObjectCompanion? = - if (clazz.companionObjectInstance is RealmObjectCompanion) { - clazz.companionObjectInstance as RealmObjectCompanion - } else null +internal actual fun realmObjectCompanionOrNull(clazz: KClass): RealmObjectCompanion? { + val cachedClass = reflectionCache[clazz] + if (cachedClass != null) { + return cachedClass + } + + val companion = try { + Class.forName("${clazz.java.name}\$Companion").kotlin + } catch (thr: Throwable) { + try { + // For Parcelable classes + Class.forName("${clazz.java.name}\$CREATOR").kotlin + } catch (thr: Throwable) { + null + } + }?.objectInstance as? RealmObjectCompanion + + if (companion != null) { + reflectionCache[clazz] = companion + } + + return companion +} + +private val reflectionCache = mutableMapOf, RealmObjectCompanion>() @PublishedApi internal actual fun realmObjectCompanionOrThrow(clazz: KClass): RealmObjectCompanion =