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

[BUG] Sextant sample navigation crashes with Android.Util.AndroidRuntimeException: 'Animators may only be run on Looper threads' #171

Closed
winterdouglas opened this issue Dec 7, 2019 · 8 comments
Labels
bug Something isn't working outdated

Comments

@winterdouglas
Copy link
Contributor

winterdouglas commented Dec 7, 2019

Describe the bug
Navigating on the Sextant Android sample makes the app crash with the exception Android.Util.AndroidRuntimeException: 'Animators may only be run on Looper threads' when running in a ReactiveCommand.

Steps To Reproduce

  1. Run the SextantSample.Android
  2. On the home page, tap on any of the buttons to navigate
  3. The app right away crashes with the exception Android.Util.AndroidRuntimeException: 'Animators may only be run on Looper threads'

Expected behavior
It shouldn't crash :)

Environment

  • OS: Android
  • Device: Tested on emulator, Huawei P20
  • Version: The ones that use RxUI >= 10.1.1
  • Working Version:
@winterdouglas winterdouglas added the bug Something isn't working label Dec 7, 2019
@open-collective-bot
Copy link

open-collective-bot bot commented Dec 7, 2019

Hey @winterdouglas 👋,

Thank you for opening an issue. We will get back to you as soon as we can. Also, check out our Open Collective and consider contributing financially.

https://opencollective.com/reactiveui

PS.: We offer priority support for all financial contributors. Don't forget to add priority label once you start contributing 😄

An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms!

@winterdouglas winterdouglas changed the title [BUG] Navigating on the Sextant sample makes the app crash with the exception Android.Util.AndroidRuntimeException: 'Animators may only be run on Looper threads' when running in a ReactiveCommand [BUG] Sextant sample navigation crashes with Android.Util.AndroidRuntimeException: 'Animators may only be run on Looper threads' Dec 7, 2019
@winterdouglas
Copy link
Contributor Author

I did a backtracking investigation already as follows:

Versions of libraries

  • Xamarin.Forms 4.2.0.910310
  • ReactiveUI.XamForms 10.5.43
    • System.Reactive 4.3.1
  • Android Support 28.0.0.3

Investigation step by step

  • Navigating by using the Navigation from the page itself works nicely
  • Changing the ReactiveCommand with an ICommand: the issue doesn't happen anymore
  • At this point I can conclude that the navigation is not the issue but something related to RxUI, Rx.Net or Xamarin.Forms
  • Next downgrading RxUI to the latest 9.x (9.22.1): The issue to go away
  • Just to make sure it's not Xamarin.Forms I manually changed the version of Xamarin to the initial one mentioned above (4.2.0.910310): The issue still persists
  • Downgrading RxUI to 10.5.31: Same results
  • Downgrading RxUI down to the version 10.1.7: Same results (checked on 10.5.7, 10.2.2, 10.1.7)
  • RxUI 10.1.5: Gives me another exception: System.TypeInitializationException: 'The type initializer for 'ReactiveUI.RxApp' threw an exception.'
  • RxUI 10.1.1: The error above happens on this version too
  • RxUI 10.0.1: Here it works again
  • RxUI 9.22.1: Works as well

All the above steps were performed with clean and rebuilt project + the app being reinstalled (uninstall/redeploy)

Apparently the issue started from the version 10.1.1 on, the only change from the version 10.0.1 to 10.1.1 is the update of Mono.Android on the following commit:
reactiveui/ReactiveUI@c4be8bc

@winterdouglas
Copy link
Contributor Author

Relates to:
#reactiveui/ReactiveUI/issues/2170

@RLittlesII
Copy link
Member

@winterdouglas Thanks for looking into this issue and the detailed report.

@winterdouglas
Copy link
Contributor Author

winterdouglas commented Dec 8, 2019

I did another round of investigation here and so far I'd say the issue is really related to the command's IsExecuting.

var canExecute = Observable
    .Return(false)
    .Delay(TimeSpan.FromSeconds(5), RxApp.TaskpoolScheduler)
    .StartWith(true)
    .ObserveOn(RxApp.MainThreadScheduler);

PushPage = ReactiveCommand
    .CreateFromObservable(() =>
        Observable.Return(Unit.Default),
        canExecute,
        outputScheduler: RxApp.MainThreadScheduler);

I can reproduce the issue with this code above. As you can see the command does nothing and the only thing that happens there is the command's canExecute being initialized as true and after 5 seconds going to false, that's enough to make the app to crash.
I could conclude also that the issue happens only when there's an UI element bound to the command, in this case a button.

@winterdouglas
Copy link
Contributor Author

winterdouglas commented Dec 8, 2019

Going a bit further with the investigation I could find that by doing the following on the view itself, the code actually breaks as well, so the real issue is not on the command's IsExecuting but on the RxApp.MainThreadScheduler that's actually not really the main thread.
In the code below the isMain will be false by using the latest RxUI version (10.5.43), so when the button's IsEnabled is set, that's not happening on the main thread.

Observable
    .Return(false)
    .Delay(TimeSpan.FromSeconds(5), RxApp.TaskpoolScheduler)
    .ObserveOn(RxApp.MainThreadScheduler)
    .Subscribe(x =>
    {
        var isMain = Xamarin.Essentials.MainThread.IsMainThread;
        PushPage.IsEnabled = x;
    });

I'm gonna create a sample with these cases and some unit tests as @RLittlesII suggested.

@winterdouglas
Copy link
Contributor Author

Ok, I now created a completely clean project with only ReactiveUI and put the exact same package versions and the code as above, I couldn't reproduce the issue anymore!

Looking further what could be the difference among them I could now find the real issue, it happens because on the Sextant sample the target/compile framework for the Android project is Android 8.1 while in the newly created one is Android 9, that makes the difference.
I noticed that when the project targets Android 8.1 a DefaultScheduler is resolved while when targeting Android 9 the correct scheduler is resolved.

Sextant sample (compiled using Android 8.1)
sextant-sample

Clean sample (compiled using Android 9)
clean-sample

@RLittlesII
Copy link
Member

Resolved By: #172

@lock lock bot added the outdated label Mar 10, 2020
@lock lock bot locked and limited conversation to collaborators Mar 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working outdated
Projects
None yet
Development

No branches or pull requests

2 participants