bluelinelabs / Conductor

A small, yet full-featured framework that allows building View-based Android applications
Apache License 2.0
3.9k stars 343 forks source link

postDestroy called without corresponding create events #598

Open PaulWoitaschek opened 4 years ago

PaulWoitaschek commented 4 years ago

I have a custom lifecycle owner which is different to the library one because it uses the pre events due to different reasons:

class ControllerLifecycleOwner<T>(lifecycleController: T) : LifecycleOwner where T : Controller, T : LifecycleOwner {

  private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleController)

  init {
    lifecycleController.addLifecycleListener(object : LifecycleListener {

      override fun preContextAvailable(controller: Controller) {
        lifecycleRegistry.handleLifecycleEvent(Event.ON_CREATE)
      }

      override fun preCreateView(controller: Controller) {
        lifecycleRegistry.handleLifecycleEvent(Event.ON_START)
      }

      override fun preAttach(controller: Controller, view: View) {
        lifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME)
      }

      override fun postDetach(controller: Controller, view: View) {
        lifecycleRegistry.handleLifecycleEvent(Event.ON_PAUSE)
      }

      override fun postDestroyView(controller: Controller) {
        lifecycleRegistry.handleLifecycleEvent(Event.ON_STOP)
      }

      override fun postDestroy(controller: Controller) {
        lifecycleRegistry.handleLifecycleEvent(Event.ON_DESTROY)
      }
    })
  }

  override fun getLifecycle(): Lifecycle = lifecycleRegistry
}

I'm now seeing crashes in postDestroy:

Caused by java.lang.IllegalArgumentException
       at androidx.lifecycle.LifecycleRegistry.downEvent(LifecycleRegistry.java:263)
       at androidx.lifecycle.LifecycleRegistry.backwardPass(LifecycleRegistry.java:314)
       at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:334)
       at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
       at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
       at com.yazio.android.sharedui.conductor.ControllerLifecycleOwner$1.postDestroy(ControllerLifecycleOwner.java:39)
       at com.bluelinelabs.conductor.Controller.performDestroy(Controller.java:1110)
       at com.bluelinelabs.conductor.Controller.removeViewReference(Controller.java:1005)
       at com.bluelinelabs.conductor.Controller.destroy(Controller.java:1131)
       at com.bluelinelabs.conductor.Controller.destroy(Controller.java:1116)
       at com.bluelinelabs.conductor.Backstack.pop(Backstack.java:62)
       at com.bluelinelabs.conductor.Backstack.popAll(Backstack.java:79)
       at com.bluelinelabs.conductor.Router.destroy(Router.java:224)
       at com.bluelinelabs.conductor.ControllerHostedRouter.destroy(ControllerHostedRouter.java:90)
       at com.bluelinelabs.conductor.Controller.destroy(Controller.java:1127)
       at com.bluelinelabs.conductor.Controller.activityDestroyed(Controller.java:872)
       at com.bluelinelabs.conductor.Router.onActivityDestroyed(Router.java:613)
       at com.bluelinelabs.conductor.ActivityHostedRouter.onActivityDestroyed(ActivityHostedRouter.java:61)
       at com.bluelinelabs.conductor.internal.LifecycleHandler.destroyRouters(LifecycleHandler.java:210)
       at com.bluelinelabs.conductor.internal.LifecycleHandler.onDestroy(LifecycleHandler.java:162)
       at android.app.Fragment.performDestroy(Fragment.java:2825)
       at android.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1461)
       at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1586)
       at android.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1658)
       at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManagerImpl.java:3068)
       at android.app.FragmentManagerImpl.dispatchDestroy(FragmentManagerImpl.java:3048)
       at android.app.FragmentController.dispatchDestroy(FragmentController.java:250)
       at android.app.Activity.performDestroy(Activity.java:8328)
       at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1348)
       at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:5530)
       at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:5575)
       at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:44)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2373)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:213)
       at android.app.ActivityThread.main(ActivityThread.java:8147)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

The corresponding source is: https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/lifecycle/lifecycle-runtime/src/main/java/androidx/lifecycle/LifecycleRegistry.java#263

So it seems all the above events were never called but postDestroy.