2021-01-09 01:34

Repeated back and forth Navigation in Android, appears to recreate the First View Model a second time

🔙 Regression

In a simple example (as well as real world apps), there is some unexpected behaviour if you have two activities with view models, and a button on each that Navigates from the First to the Second and then the Second back to the first (via a close).

If you repeated click on each button, going through this open close cycle, at some point after hitting for around 10 seconds causes the first View Model to be created on the almost like it is doing a full Navigate rather than closing the top level activity.

Is this normal behaviour, and is the fix just to add some sort of delay to the close button?

Old (and correct) behaviour

Should not recreate the first view model (this does not appear to be a problem in 4.4.4)

Current behaviour

After about 10 seconds of repeated clicking on the button in the first view and then the second view

Reproduction steps

Simple example based on TipCalc avail here


Click on button on each activity constantly for about 10 seconds. You have got to do this fast, most easily on a real device.

You Get



Version: 6.2.2

Platform: - [ ] :iphone: iOS - [X ] :robot: Android - [ ] :checkered_flag: WPF - [ ] :earth_americas: UWP - [ ] :apple: MacOS - [ ] :tv: tvOS - [ ] :monkey: Xamarin.Forms


  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答


  • weixin_39537397 weixin_39537397 4月前

    The repro repo is accessible. Please provide repro steps.

    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    Hi Cheesebaron, sorry for the delay, I have made the repo public, hope to hear your thoughts.

    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    I have replicated in my main development project :(, the first view model is recreated if you exit the second then click on a button or grid to open the second view model again.

    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    I noticed that this problem does not happen with Animations turned off.

    In OnViewDestroy in MvxActivityViewExtensions,cs (MvvmCross.Droid.Support.V7.AppCompat) on line 76

    we have

    var currentActivity = Mvx.IoCProvider.Resolve()?.Activity; if (currentActivity == null && view is Activity destroyedActivity && destroyedActivity.IsFinishing && Mvx.IoCProvider.TryResolve(out var appStart)) { appStart?.ResetStart(); }

    Is it possible that during a slower animation the top activity returned is null, causing the restart?

    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    I created my own version of the MvxCompatActivity that uses a version of MvxActivityViewExtensions in my Main Dev project, used that instead of the normal one, and found I can get it to return null and cause the app to restart. Disabling ResetStart() stops this from happening, or removing the animation has the same affect. This is a major problem on older slower devices with slower inflation.

    With the new Material Design it is easy to get a blank screen between the activity transitions, and I think this is what is causing the problem.

    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    Using https://github.com/jamesmontemagno/CurrentActivityPlugin, instead of the default one returns the activity whilst the built in one (IMvxAndroidCurrentTopActivity) returns null. The problem is here. I suspect it is due to the use of a Current Flag, there is possibly a race condition some where. I am not sure where to go from here, any ideas?

    Always grab the current Activity of your Xamarin.Android app! - jamesmontemagno/CurrentActivityPlugin
    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    GetCurrentActivity in MvxApplicationCallackCurrentTopActivity relies upon an IsCurrent field. I have managed to get it into a state where there are activities but none of them are marked as current, as if it is just between OnActivityStopped and OnActivityDestroyed. This is where null is returned.

    if (Activities.Count > 0) { var e = Activities.GetEnumerator(); while (e.MoveNext()) { var current = e.Current; if (current.Value.IsCurrent) { return current.Value.Activity; } } } return null;

    点赞 评论 复制链接分享
  • weixin_39896617 weixin_39896617 4月前

    My interim solution is to write a wrapper around the CurrentActivityPlugin to get around this, but there is something wrong that needs looking at.

    点赞 评论 复制链接分享