I'm trying to debug why `remember()` creates two d...
# compose
r
I'm trying to debug why
remember()
creates two different objects. Code inside =>
I've got this part of the code invoking the room:
Copy code
is CallState.InCall -> {
                            Room(url, s.token) {
                                val otherName = otherInfo?.name ?: stringResource(R.string.unknown_caller)
                                PreCall(stringResource(R.string.outgoing_ring), otherName, otherInfo?.imageUrl)
                            }
                        }
Copy code
fun Room(url: String, token: RoomToken, preCallView: @Composable () -> Unit) {
    DisposableEffect(url, token) {
        Timber.d { "Connecting to room ${token.roomId}" }
        onDispose {
            Timber.d { "Disposing of room ${token.roomId}" }
        }
    }

    val room = rememberLiveKitRoom(
        url = url,
        token = token.token,
        audio = true,
        video = true,
        connect = true,
    )

    Timber.d { "We got room $room" }
The logs:
Copy code
We got room io.livekit.android.room.Room@62ca600
Connecting to room RoomId(roomId=4d903c87-6e4d-40d3-89c3-d1058ac944bf)
We got room io.livekit.android.room.Room@c274e92
Connecting to room RoomId(roomId=4d903c87-6e4d-40d3-89c3-d1058ac944bf)
the livekit room:
Copy code
fun rememberLiveKitRoom(
    url: String? = null,
    token: String? = null,
    audio: Boolean = false,
    video: Boolean = false,
    connect: Boolean = true,
    roomOptions: RoomOptions? = null,
    liveKitOverrides: LiveKitOverrides? = null,
    connectOptions: ConnectOptions? = null,
    onConnected: (suspend CoroutineScope.(Room) -> Unit)? = null,
    onDisconnected: (suspend CoroutineScope.(Room) -> Unit)? = null,
    onError: ((Room, Exception?) -> Unit)? = DEFAULT_ERROR_HANDLER,
    passedRoom: Room? = null,
): Room {
    val context = LocalContext.current
    val room = remember(passedRoom) {
        passedRoom ?: LiveKit.create(
            appContext = context.applicationContext,
            options = roomOptions ?: RoomOptions(),
            overrides = liveKitOverrides ?: LiveKitOverrides(),
        )
    }
So that wasn't the issue, but the room object was being reused, which lead to... interesting consequences.
Nope, spoke too soon.
Copy code
Current state: IncomingRing(caller=5da7e19b-5908-409b-99f2-c40971125ee5, token=RoomToken(token=eyJhbGciOiJIUzI1NiJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6IjkzYjAxMjhjLWExYzItNDk2ZS1iZmJjLWQ5OTE0MWUzZTdhMSJ9LCJpc3MiOiJjbG91ZGZ1bmN0aW9ucyIsImV4cCI6MTc0ODYzNDEzNCwibmJmIjowLCJzdWIiOiIwYWZlY2NlNi1kYjUxLTQ0ZGUtOWJkMy1mNWRlOWNkZDg5ZWYifQ.qlj9i1b8_OqakU1QjMdvGyIgCizuEjPrC-MOhAEp7eg, roomId=RoomId(roomId=93b0128c-a1c2-496e-bfbc-d99141e3e7a1)))
Accepting call
We got room io.livekit.android.room.Room@6d9fc3e
Connecting to room RoomId(roomId=93b0128c-a1c2-496e-bfbc-d99141e3e7a1)
We got room io.livekit.android.room.Room@ab44ac8
Connecting to room RoomId(roomId=93b0128c-a1c2-496e-bfbc-d99141e3e7a1)
State is InCall(other=5da7e19b-5908-409b-99f2-c40971125ee5, token=RoomToken(token=eyJhbGciOiJIUzI1NiJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6IjkzYjAxMjhjLWExYzItNDk2ZS1iZmJjLWQ5OTE0MWUzZTdhMSJ9LCJpc3MiOiJjbG91ZGZ1bmN0aW9ucyIsImV4cCI6MTc0ODYzNDEzNCwibmJmIjowLCJzdWIiOiIwYWZlY2NlNi1kYjUxLTQ0ZGUtOWJkMy1mNWRlOWNkZDg5ZWYifQ.qlj9i1b8_OqakU1QjMdvGyIgCizuEjPrC-MOhAEp7eg, roomId=RoomId(roomId=93b0128c-a1c2-496e-bfbc-d99141e3e7a1)))
Tracks: []
Other tracks: []
State is InCall(other=5da7e19b-5908-409b-99f2-c40971125ee5, token=RoomToken(token=eyJhbGciOiJIUzI1NiJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6IjkzYjAxMjhjLWExYzItNDk2ZS1iZmJjLWQ5OTE0MWUzZTdhMSJ9LCJpc3MiOiJjbG91ZGZ1bmN0aW9ucyIsImV4cCI6MTc0ODYzNDEzNCwibmJmIjowLCJzdWIiOiIwYWZlY2NlNi1kYjUxLTQ0ZGUtOWJkMy1mNWRlOWNkZDg5ZWYifQ.qlj9i1b8_OqakU1QjMdvGyIgCizuEjPrC-MOhAEp7eg, roomId=RoomId(roomId=93b0128c-a1c2-496e-bfbc-d99141e3e7a1)))
resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
Tracks: []
Other tracks: []
We got room io.livekit.android.room.Room@6d9fc3e
We got room io.livekit.android.room.Room@ab44ac8
stop(223): called with 4320 frames delivered
Disposing of room RoomId(roomId=93b0128c-a1c2-496e-bfbc-d99141e3e7a1)
EGLNativeWindowType 0xe6589738 disconnect failed
Skipped 123 frames!  The application may be doing too much work on its main thread.
We got room io.livekit.android.room.Room@ab44ac8
Somehow the old room is still alive?
Something utterly weird, I've got
Copy code
LaunchedEffect(state) {
                Timber.d { "State is $state" }
            }
But the logs show me:
Copy code
2025-05-30 22:04:58.849 10920-10920 CallActivity$onCreate   me.getreach.jakiro                   D  State is InCall(other=5da7e19b-5908-409b-99f2-c40971125ee5, token=RoomToken(token=eyJhbGciOiJIUzI1NiJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6IjFkOTIyZWQzLWZkZGItNGI3MS1iNmJmLWNhODVkMmM2MzkzZSJ9LCJpc3MiOiJjbG91ZGZ1bmN0aW9ucyIsImV4cCI6MTc0ODYzNTc5MiwibmJmIjowLCJzdWIiOiIwYWZlY2NlNi1kYjUxLTQ0ZGUtOWJkMy1mNWRlOWNkZDg5ZWYifQ.GGkoh0WkiM_ANxQVmAmc3F3eKcy99ExQE0Ft4FI05i4, roomId=RoomId(roomId=1d922ed3-fddb-4b71-b6bf-ca85d2c6393e)))
2025-05-30 22:04:58.885 10920-10920 CallActivity$onCreate   me.getreach.jakiro                   D  State is InCall(other=5da7e19b-5908-409b-99f2-c40971125ee5, token=RoomToken(token=eyJhbGciOiJIUzI1NiJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6IjFkOTIyZWQzLWZkZGItNGI3MS1iNmJmLWNhODVkMmM2MzkzZSJ9LCJpc3MiOiJjbG91ZGZ1bmN0aW9ucyIsImV4cCI6MTc0ODYzNTc5MiwibmJmIjowLCJzdWIiOiIwYWZlY2NlNi1kYjUxLTQ0ZGUtOWJkMy1mNWRlOWNkZDg5ZWYifQ.GGkoh0WkiM_ANxQVmAmc3F3eKcy99ExQE0Ft4FI05i4, roomId=RoomId(roomId=1d922ed3-fddb-4b71-b6bf-ca85d2c6393e)))
Directly one after another.
Why isn't compose doing its job here?
There should only be one line.
huh, nah, it's something else,
Copy code
lifecycleScope.launch {
            _callState.collect {
                Timber.d { "collect State is $it" }
            }
        }
Also fires twice.
Ah great. Android is creating two
Activity
even though I told it I want
singleInstance