Skip to content

Check isInitialized before updating footer text#10483

Closed
Goooler wants to merge 1 commit intothunderbird:mainfrom
Goooler:isInitialized
Closed

Check isInitialized before updating footer text#10483
Goooler wants to merge 1 commit intothunderbird:mainfrom
Goooler:isInitialized

Conversation

@Goooler
Copy link
Contributor

@Goooler Goooler commented Feb 5, 2026

This exception happens when opening the app when it's recycled (I guess).

kotlin.UninitializedPropertyAccessException: lateinit property adapter has not been initialized
  at com.fsck.k9.ui.messagelist.BaseMessageListFragment.updateFooterText(BaseMessageListFragment.kt:1441)
  at com.fsck.k9.ui.messagelist.BaseMessageListFragment.updateFooterText(BaseMessageListFragment.kt:1437)
  at com.fsck.k9.ui.messagelist.BaseMessageListFragment.folderLoading(BaseMessageListFragment.kt:763)
  at com.fsck.k9.ui.messagelist.MessageListHandler.handleMessage(MessageListHandler.java:88)
  at android.os.Handler.dispatchMessage(Handler.java:132)
  at android.os.Looper.dispatchMessage(Looper.java:333)
  at android.os.Looper.loopOnce(Looper.java:263)
  at android.os.Looper.loop(Looper.java:367)
  at android.app.ActivityThread.main(ActivityThread.java:9287)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)

This exception happens when opening the app when it's recycled (I guess).

```
kotlin.UninitializedPropertyAccessException: lateinit property adapter has not been initialized
  at com.fsck.k9.ui.messagelist.BaseMessageListFragment.updateFooterText(BaseMessageListFragment.kt:1441)
  at com.fsck.k9.ui.messagelist.BaseMessageListFragment.updateFooterText(BaseMessageListFragment.kt:1437)
  at com.fsck.k9.ui.messagelist.BaseMessageListFragment.folderLoading(BaseMessageListFragment.kt:763)
  at com.fsck.k9.ui.messagelist.MessageListHandler.handleMessage(MessageListHandler.java:88)
  at android.os.Handler.dispatchMessage(Handler.java:132)
  at android.os.Looper.dispatchMessage(Looper.java:333)
  at android.os.Looper.loopOnce(Looper.java:263)
  at android.os.Looper.loop(Looper.java:367)
  at android.app.ActivityThread.main(ActivityThread.java:9287)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)
```
@Goooler
Copy link
Contributor Author

Goooler commented Feb 5, 2026

BTW, whey not mark adapter lazy instead of lateinit? This should eliminate most isInitialized checks in related cases.

@mohitsatr
Copy link
Contributor

FATAL EXCEPTION: main (Ask Gemini)
Process: net.thunderbird.android.debug, PID: 15660
kotlin.UninitializedPropertyAccessException: lateinit property adapter has not been initialized
     at com.fsck.k9.ui.messagelist.BaseMessageListFragment.resetActionMode(BaseMessageListFragment.kt: 
     at com.fsck.k9.ui.messagelist.BaseMessageListFragment.setActive(BaseMessageListFragment.kt:284)
     at com.fsck.k9.activity.MessageHomeActivity.setFullyActive(MessageHomeActivity.kt:1454)
     at com.fsck.k9.activity.MessageHomeActivity.onBackStackChanged(MessageHomeActivity.kt:1143)
     at androidx.fragment.app.FragmentManager.reportBackStackChanged(FragmentManager.java:2403)
     at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2239)
     at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2115)
     at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2052)
     at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:703)
     at android.os.Handler.handleCallback(Handler.java:995)
     at android.os.Handler.dispatchMessage(Handler.java:103)
     at android.os.Looper.loopOnce(Looper.java:273)
     at android.os.Looper.loop(Looper.java:363)
     at android.app.ActivityThread.main(ActivityThread.java:10060)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
2026-02-06 09:55:51.151 15660-15660 ExceptionHandler        net.thunderbird.android.debug        E  UncaughtException

@Goooler
Copy link
Contributor Author

Goooler commented Feb 6, 2026

Yeah, this is another example, so many call sites of adapter need to be checked for isInitialized.

@rafaeltonholo
Copy link
Member

Hello! Thank you for raising this issue. We're aware of the crash you're experiencing, and it has been addressed in the PR #10469.

As we gradually update the MessageList state, some crashes like this are expected to occur on the main branch. If this is causing problems for your development, please consider disabling the feature flag enable_message_list_new_state, which you can find in MessageListFeatureFlags.

The fix I implemented will delay the call of updateFooterText, but that may not be necessary. @mohitsatr, could you please provide the steps to reproduce the crash you encountered? I want to ensure that the solution in #10469 also addresses that issue. If it doesn't, we can proceed with this fix, and I'll investigate the other one further.

To answer your question:

Why not mark the adapter as lazy instead of lateinit? This should eliminate most isInitialized checks in related cases.

There are a few reasons for this:

  1. Using by lazy on instances that hold the Activity/Fragment context can potentially lead to memory leaks, so it's best to avoid it.
  2. The BaseMessageListFragment is quite complex, and even minor changes can lead to unpredictable side effects. This situation is a good example of that.
  3. Transitioning the adapter from lateinit to by lazy would necessitate more changes than we intend to make at this time, which could inadvertently affect the LegacyMessageListFragment. This is something we want to avoid.

Thanks for your understanding!

@Goooler
Copy link
Contributor Author

Goooler commented Feb 6, 2026

Thanks for the explanation!

@Goooler Goooler closed this Feb 6, 2026
@Goooler Goooler deleted the isInitialized branch February 6, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants