Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on language change #107

Closed
ro-mak opened this issue Oct 19, 2022 · 8 comments
Closed

Crash on language change #107

ro-mak opened this issue Oct 19, 2022 · 8 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@ro-mak
Copy link

ro-mak commented Oct 19, 2022

To reproduce

  1. Open a fragment that is clearing some stuff via viewbinding in onDestroyView
  2. Minimize app
  3. Change system locale
  4. Reopen app
  5. Crash!

Is it an intended behaviour?

If it is i think it should be mentioned in Readme
I saw that there is a special callback onViewDestroyed, maybe that's the right place to clear some stuff?

@kirich1409 kirich1409 self-assigned this Oct 21, 2022
@kirich1409 kirich1409 added the bug Something isn't working label Oct 21, 2022
@kirich1409
Copy link
Collaborator

Hi, @ro-mak. Can you share stack trace of the crash?

@ro-mak
Copy link
Author

ro-mak commented Oct 21, 2022

Hi, @kirich1409, here it is, and below I added the project

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.fragmentviewbindingtest, PID: 18170
    java.lang.RuntimeException: Unable to destroy activity {com.example.fragmentviewbindingtest/com.example.fragmentviewbindingtest.MainActivity}: java.lang.IllegalStateException: Access to viewBinding after Lifecycle is destroyed or hasn't created yet. The instance of viewBinding will be not cached.
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5387)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5420)
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5714)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5630)
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71)
        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
        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:2210)
        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:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
     Caused by: java.lang.IllegalStateException: Access to viewBinding after Lifecycle is destroyed or hasn't created yet. The instance of viewBinding will be not cached.
        at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.runStrictModeChecks(ViewBindingProperty.kt:112)
        at by.kirich1409.viewbindingdelegate.LifecycleViewBindingProperty.getValue(ViewBindingProperty.kt:91)
        at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue(FragmentViewBindings.kt:63)
        at by.kirich1409.viewbindingdelegate.FragmentViewBindingProperty.getValue(FragmentViewBindings.kt:52)
        at com.example.fragmentviewbindingtest.ui.main.MainFragment.getViewBinding(MainFragment.kt:21)
        at com.example.fragmentviewbindingtest.ui.main.MainFragment.onDestroyView(MainFragment.kt:37)
        at androidx.fragment.app.Fragment.performDestroyView(Fragment.java:3232)
        at androidx.fragment.app.FragmentStateManager.destroyFragmentView(FragmentStateManager.java:744)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:327)
        at androidx.fragment.app.SpecialEffectsController$FragmentStateManagerOperation.complete(SpecialEffectsController.java:771)
        at androidx.fragment.app.SpecialEffectsController$Operation.cancel(SpecialEffectsController.java:615)
        at androidx.fragment.app.SpecialEffectsController.forceCompleteAllOperations(SpecialEffectsController.java:350)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2844)
        at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:2820)
        at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:345)
        at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:306)
        at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:280)
        at android.app.Activity.performDestroy(Activity.java:8316)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1364)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5374)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5420) 
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5714) 
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5630) 
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:71) 
        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) 
        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:2210) 
        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:7839) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 

@ro-mak
Copy link
Author

ro-mak commented Oct 21, 2022

here is the test project
https://github.com/ro-mak/FragmentViewBindingTest

@kirich1409
Copy link
Collaborator

Cleaning reference to view binding and detection of current lifecycle state is based on Jetpack Lifecycle library. Need to check it's behaviour during config changes

@kirich1409
Copy link
Collaborator

As temporary solution yon can use

class MainFragment : Fragment() {

    companion object {
        fun newInstance() = MainFragment()
    }

    private lateinit var viewModel: MainViewModel

    private val viewBinding: FragmentMainBinding by viewBinding(FragmentMainBinding::bind, onViewDestroyed = {viewBinding - > viewBinding.main.minHeight = 100}
)

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        // TODO: Use the ViewModel
    }

}

@kirich1409
Copy link
Collaborator

I've tried to reproduce bug in 1.5.8. I checked on Android 13 emulator. No crash

@Reginer
Copy link

Reginer commented Feb 17, 2023

ViewBindingPropertyDelegate.strictMode = false

@kirich1409
Copy link
Collaborator

Will be fixed in 2.0.0

@kirich1409 kirich1409 added this to the 2.0.0 milestone Jan 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants