I'm using 5 beta, trying to make retainedKodein wo...
# kodein
m
I'm using 5 beta, trying to make retainedKodein work but it crashes for me:
Copy code
Caused by: java.lang.IllegalStateException: Fragment org.kodein.android.KodeinFragment must be a public static class to be  properly recreated from instance state.
        at android.app.BackStackRecord.doAddOp(BackStackRecord.java:429)
        at android.app.BackStackRecord.add(BackStackRecord.java:409)
        at org.kodein.android.RetainedKt$retainedKodein$1.invoke(retained.kt:26)
        at org.kodein.android.RetainedKt$retainedKodein$1.invoke(Unknown Source:0)
        at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131)
...
anybody experienced the same?
setting fragment to public seems to solve
or not, if I copy the retained.kt to my project it works even with private
s
I’m surprised you can even build/compile it.
KodeinFragment
is a
private final class
when looking at the kodein-framework-android dependency contents This means you can’t instantiate nor subclass from it. And every Android concrete Fragment must be public and have a public empty/default constructor.
nah I'm stupid
s
Ah.... it is created privately by a factory (
Activity.retainedKodein
). Still, a concrete fragment must have a public empty/default constructor. If not, your app will crash when a configuration change (e.g rotation of the phone) happens. This seems to be a bug in Kodein. @salomonbrys Is this a bug?
m
retainedKodein is just a shortcut for having a simple kodein with everything scoped with activityRetainedScope right?
s
@streetsofboston This is very weird.
KodeinFragment
is supposed to be registered as a retained fragment. So it should not be recreated by the system as it should be preserved between config changes.
OK, so this is a Kodein Bug, thanks a lot for reporting it
Whether it is a retained fragment or not, Android will complain if the fragment's class dpes not conforms to standard fragments form (from Nougat and over) as the code clearly shows here : https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/BackStackRecord.java#L429
s
Yep. In short, the creation of Fragments is up to the Android Framework and when you try to fight that, you’ll get into trouble 🙂 To be sure the Android Framework can do this, Fragments must have public empty/default constructors. Note that the Fragment may not be retained and the Android Framework creates a new one on a configuration change. To make sure it is retained between config changes, call
setRetainInstance(true)
on the Fragment
😉
s
Hah…. yep, you did set that retain-instance to true. And still, the platform likes to create one after a rotation… weird. I guess it is just pro-active in ‘warning’ you about not having a public default constructor 🙂
s
AFAIU, the platform will not recreate it (because
setRetainInstance(true)
), but it does still check the conformity 😞
s
I guess it does that in case the app needs to be restored after its process has being killed when it was in the background.
s
...didn't think about that 😉