thunderbird / thunderbird-android

Thunderbird for Android – Open Source Email App for Android (fka K-9 Mail)
https://thunderbird.net/mobile
Apache License 2.0
11.05k stars 2.51k forks source link

Fix navigation ConcurrentModificationException issue #8494

Closed wmontwe closed 3 weeks ago

wmontwe commented 3 weeks ago

This change prevents a ConcurrentModificationException that could occur when interacting with fragments nested inside composables. This exception was caused by a timing issue between the fragment's lifecycle and the composable it's embedded in, especially when handling fragment results.

Exception java.util.ConcurrentModificationException:
  at java.util.AbstractList$Itr.checkForComodification (AbstractList.java:401)
  at java.util.AbstractList$Itr.next (AbstractList.java:370)
  at androidx.navigation.NavController.lifecycleObserver$lambda$2 (NavController.kt:196)
  at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent (LifecycleRegistry.jvm.kt:320)
  at androidx.lifecycle.LifecycleRegistry.forwardPass (LifecycleRegistry.jvm.kt:257)
  at androidx.lifecycle.LifecycleRegistry.sync (LifecycleRegistry.jvm.kt:293)
  at androidx.lifecycle.LifecycleRegistry.moveToState (LifecycleRegistry.jvm.kt:142)
  at androidx.lifecycle.LifecycleRegistry.setCurrentState (LifecycleRegistry.jvm.kt:107)
  at androidx.navigation.NavBackStackEntry.updateState (NavBackStackEntry.kt:195)
  at androidx.navigation.NavBackStackEntry.handleLifecycleEvent (NavBackStackEntry.kt:178)
  at androidx.navigation.NavController.lifecycleObserver$lambda$2 (NavController.kt:197)
  at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent (LifecycleRegistry.jvm.kt:320)
  at androidx.lifecycle.LifecycleRegistry.forwardPass (LifecycleRegistry.jvm.kt:257)
  at androidx.lifecycle.LifecycleRegistry.sync (LifecycleRegistry.jvm.kt:293)
  at androidx.lifecycle.LifecycleRegistry.moveToState (LifecycleRegistry.jvm.kt:142)
  at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent (LifecycleRegistry.jvm.kt:124)
  at androidx.lifecycle.ReportFragment$Companion.dispatch$lifecycle_runtime_release (ReportFragment.android.kt:190)
  at androidx.lifecycle.ReportFragment$LifecycleCallbacks.onActivityPostStarted (ReportFragment.android.kt:119)
  at android.app.Activity.dispatchActivityPostStarted (Activity.java:1379)
  at android.app.Activity.performStart (Activity.java:8112)
  at android.app.ActivityThread.handleStartActivity (ActivityThread.java:3700)
  at android.app.servertransaction.TransactionExecutor.performLifecycleSequence (TransactionExecutor.java:221)
  at android.app.servertransaction.TransactionExecutor.cycleToPath (TransactionExecutor.java:201)
  at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:173)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2247)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at android.app.ActivityThread.main (ActivityThread.java:7881)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:568)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1045)

Steps to reproduce:

cketti commented 3 weeks ago

What are the steps to reproduce the crash?

wmontwe commented 3 weeks ago

What are the steps to reproduce the crash?

See above, updated

cketti commented 3 weeks ago

Note: I wasn't able to reproduce this on a physical device. It reproduces fine for me on an emulator using the "Google Play Intel x86_64 Atom System Image, API 31" image.