androidbroadcast / ViewBindingPropertyDelegate

Make work with Android View Binding simpler
https://proandroiddev.com/make-android-view-binding-great-with-kotlin-b71dd9c87719
Apache License 2.0
1.42k stars 102 forks source link

IllegalStateException: Fragment's view can't be accessed. Fragment isn't added. - when trying to restore fragment state #109

Closed Scorpionstvo closed 1 year ago

Scorpionstvo commented 1 year ago

From Fragment A on button click I go to Fragment B adding to the stack so I can return to Fragment A on back button. In Fragment A, I'm saving the state with onSaveInstanceState. When I am in Fragment B and rotate the screen, the app crashes with an error: IllegalStateException: Fragment is not attached to Activity. this is how I load fragments in Activity:

supportFragmentManager.commit {
        replace(R.id.detail_container, NewChatFragment())  // launch fragment A
    }

 supportFragmentManager.commit {
        replace(R.id.detail_container, NewContactFragment()).addToBackStack(null) // launch fragment B
    }

Fragment A:

class NewChatFragment : DetailBaseFragment(R.layout.fragment_new_chat) {
    private val binding by viewBinding(
        FragmentNewChatBinding::bind
    )
    private var title: String? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if (savedInstanceState != null) title = savedInstanceState.getString("key")
        setTitle()
        initButtons()
    }

 override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        val savedTitle = binding.tvTitle.text.toString()
        outState.putString("key", savedTitle)

    }

StackTrace: java.lang.IllegalStateException: Fragment's view can't be accessed. Fragment isn't added at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue(ViewBindingProperty.kt:87) at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue(FragmentViewBindings.kt:63) at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue(FragmentViewBindings.kt:52) at com.xabber.presentation.application.fragments.chatlist.add.NewChatFragment.getBinding(NewChatFragment.kt:12) at com.xabber.presentation.application.fragments.chatlist.add.NewChatFragment.onSaveInstanceState(NewChatFragment.kt:44) at androidx.fragment.app.Fragment.performSaveInstanceState(Fragment.java:3288) at androidx.fragment.app.FragmentStateManager.saveBasicState(FragmentStateManager.java:681) at androidx.fragment.app.FragmentStateManager.saveState(FragmentStateManager.java:647) at androidx.fragment.app.FragmentStore.saveActiveFragments(FragmentStore.java:214) at androidx.fragment.app.FragmentManager.saveAllStateInternal(FragmentManager.java:2380) at androidx.fragment.app.FragmentManager.lambda$attachController$4$androidx-fragment-app-FragmentManager(FragmentManager.java:2658) at androidx.fragment.app.FragmentManager$$ExternalSyntheticLambda4.saveState(Unknown Source:2) at androidx.savedstate.SavedStateRegistry.performSave(SavedStateRegistry.kt:247) at androidx.savedstate.SavedStateRegistryController.performSave(SavedStateRegistryController.kt:81) at androidx.activity.ComponentActivity.onSaveInstanceState(ComponentActivity.java:368) at android.app.Activity.performSaveInstanceState(Activity.java:2088) at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1486) at android.app.ActivityThread.callActivityOnSaveInstanceState(ActivityThread.java:5419) at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4732) at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5367) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5302) at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:224)

kirich1409 commented 1 year ago

It is expected behaviour of the library. Working with a ViewBinding is allowed only between onViewCreated and onDestroyView. The best place for keeping text is ViewModel or keep it as separate property in Fragment