Fix crash when calling Room.predecessorRoom when the room is destroyed (#5894)

* Fix crash when calling `Client.predecessorRoom` when the room is destroyed

* Handle the root cause of this crash: destroying the room on activity recreation
This commit is contained in:
Jorge Martin Espinosa
2025-12-15 10:25:08 +01:00
committed by GitHub
parent b03b6b3da8
commit aaf788b448
2 changed files with 16 additions and 3 deletions

View File

@@ -8,7 +8,9 @@
package io.element.android.appnav.room.joined
import android.app.Activity
import android.os.Parcelable
import androidx.activity.compose.LocalActivity
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
@@ -96,6 +98,9 @@ class JoinedRoomLoadedFlowNode(
private val callback: Callback = callback()
override val graph = roomGraphFactory.create(inputs.room)
// This is an ugly hack to check activity recreation
private var currentActivity: Activity? = null
init {
lifecycle.subscribe(
onCreate = {
@@ -115,8 +120,12 @@ class JoinedRoomLoadedFlowNode(
},
onDestroy = {
Timber.v("OnDestroy")
activeRoomsHolder.removeRoom(inputs.room.sessionId, inputs.room.roomId)
inputs.room.destroy()
// If we're just going through an activity recreation there's no need to destroy the Room object
// Destroying it would actually cause an issue where its methods can no longer be called
if (currentActivity?.isChangingConfigurations != true) {
activeRoomsHolder.removeRoom(inputs.room.sessionId, inputs.room.roomId)
inputs.room.destroy()
}
appNavigationStateService.onLeavingRoom(id)
}
)
@@ -289,6 +298,8 @@ class JoinedRoomLoadedFlowNode(
@Composable
override fun View(modifier: Modifier) {
currentActivity = LocalActivity.current
BackstackView()
}
}

View File

@@ -85,7 +85,9 @@ class RustBaseRoom(
}.stateIn(roomCoroutineScope, started = SharingStarted.Lazily, initialValue = initialRoomInfo)
override fun predecessorRoom(): PredecessorRoom? {
return innerRoom.predecessorRoom()?.map()
return runCatchingExceptions { innerRoom.predecessorRoom()?.map() }
.onFailure { Timber.e(it, "Could not get predecessor room") }
.getOrNull()
}
override suspend fun subscribeToSync() = roomSyncSubscriber.subscribe(roomId)