App resuming results in crash with FormsAppCompatActivity

霸气de小男生 提交于 2019-12-30 18:53:18

问题


I have a Xamarin Forms app, currently being built for Android. I have a MainActivity that used to extend FormsApplicationActivity, but because I want to use a custom theme I had to change it to extend FormsAppCompatActivity (see my other question: Xamarin Forms custom theme not working).

Ever since changing from FormsApplicationActivity to FormsAppCompatActivity the app crashes whenever I switch out of the app and then back into the app. It throws an error in the App.xaml.cs class in the OnResume method, where I try to set the MainPage to a new navigation page:

protected override void OnResume()
{
    bool isRegistered = _authenticationService.IsRegistered();

    MainPage = isRegistered 
        ? new NavigationPage(new LoginPage()) 
        : new NavigationPage(new RegisterPage()); // this results in the crash
}

The error I'm getting is:

Java.Lang.IllegalStateException: Can not perform this action after onSaveInstanceState

This is the stacktrace:

03-09 13:43:52.098 I/MonoDroid( 1243): Java.Lang.IllegalStateException: Can not perform this action after onSaveInstanceState
03-09 13:43:52.098 I/MonoDroid( 1243):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/2098/3efa14c4/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Android.Runtime.JNIEnv.CallIntMethod (IntPtr jobject, IntPtr jmethod) [0x00063] in /Users/builder/data/lanes/2098/3efa14c4/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:386 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Android.Support.V4.App.FragmentTransactionInvoker.Commit () [0x00033] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.SwitchContentAsync (Xamarin.Forms.Page view, Boolean animated, Boolean removed, Boolean popToRoot) [0x000e1] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnPushAsync (Xamarin.Forms.Page view, Boolean animated) [0x00000] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.PushViewAsync (Xamarin.Forms.Page page, Boolean animated) [0x00000] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.<OnElementChanged>b__13_0 (Xamarin.Forms.Page p) [0x00000] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.EnumerableExtensions.ForEach[T] (IEnumerable`1 enumeration, System.Action`1 action) [0x00010] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnElementChanged (Xamarin.Forms.Platform.Android.ElementChangedEventArgs`1 e) [0x001af] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetElement (Xamarin.Forms.Platform.Android.TElement element) [0x000fc] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00027] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001f] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.RendererFactory.GetRenderer (Xamarin.Forms.VisualElement view) [0x00000] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.Platform.AddChild (Xamarin.Forms.Page page, Boolean layout) [0x00015] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.AppCompat.Platform.SetPage (Xamarin.Forms.Page newRoot) [0x00090] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.InternalSetPage (Xamarin.Forms.Page page) [0x0001a] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.AppOnPropertyChanged (System.Object sender, System.ComponentModel.PropertyChangedEventArgs args) [0x0001e] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.BindableObject.OnPropertyChanged (System.String propertyName) [0x00012] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Application.set_MainPage (Xamarin.Forms.Page value) [0x0008b] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Smartbit.App.OnResume () [0x00020] in C:\Users\leonc\Documents\Visual Studio 2015\Projects\Smartbit\Smartbit\Smartbit\App.xaml.cs:52 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Application.SendResume () [0x00006] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnStateChanged () [0x00039] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnRestart () [0x00019] in <filename unknown>:0 
03-09 13:43:52.098 I/MonoDroid( 1243):   at Android.App.Activity.n_OnRestart (IntPtr jnienv, IntPtr native__this) [0x00009] in /Users/builder/data/lanes/2098/3efa14c4/source/monodroid/src/Mono.Android/platforms/android-23/src/generated/Android.App.Activity.cs:4539 
03-09 13:43:52.098 I/MonoDroid( 1243):   at (wrapper dynamic-method) System.Object:cba7a870-1435-4f70-9059-e10915aba0c0 (intptr,intptr)
03-09 13:43:52.098 I/MonoDroid( 1243):   --- End of managed exception stack trace ---
03-09 13:43:52.098 I/MonoDroid( 1243): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1448)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1466)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:634)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613)
03-09 13:43:52.098 I/MonoDroid( 1243):  at md5b60ffeb829f638581ab2bb9b1a7f4f3f.FormsAppCompatActivity.n_onRestart(Native Method)
03-09 13:43:52.098 I/MonoDroid( 1243):  at md5b60ffeb829f638581ab2bb9b1a7f4f3f.FormsAppCompatActivity.onRestart(FormsAppCompatActivity.java:86)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.Instrumentation.callActivityOnRestart(Instrumentation.java:1181)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.Activity.performRestart(Activity.java:5291)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.Activity.performResume(Activity.java:5302)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2764)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.os.Handler.dispatchMessage(Handler.java:102)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.os.Looper.loop(Looper.java:136)
03-09 13:43:52.098 I/MonoDroid( 1243):  at android.app.ActivityThread.main(ActivityThread.java:5001)
03-09 13:43:52.098 I/MonoDroid( 1243):  at java.lang.reflect.Method.invokeNative(Native Method)
03-09 13:43:52.098 I/MonoDroid( 1243):  at java.lang.reflect.Method.invoke(Method.java:515)
03-09 13:43:52.098 I/MonoDroid( 1243):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
03-09 13:43:52.098 I/MonoDroid( 1243):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
03-09 13:43:52.098 I/MonoDroid( 1243):  at dalvik.system.NativeStart.main(Native Method)

回答1:


I had the similiar issue. There are few points about it:

1) Move your MainPage setting code to App constructor. As MainPage should be set in OnCreate method.

public App () {
    MainPage = isRegistered 
                ? new NavigationPage(new LoginPage()) 
                : new NavigationPage(new RegisterPage()); 
}

2) You need to set you root page before OnCreate finishes. As you do not know the page you need, you may just set blanc page.

public App () {
     MainPage = new ContentPage();
}

3) If this does not help. You can simply add try/catch block abound MainPage setter. This is dirty solution, but it works. In AppCompatActivity xamarin uses Fragments not Views. The crash happens, when android tries to restore fragment state. On plain android we used to use CommitAllowingStateLoss().

try{
       MainPage = isRegistered 
            ? new NavigationPage(new LoginPage()) 
            : new NavigationPage(new RegisterPage()); 
}catch(Exception){}



回答2:


I solved it by adding a thread sleep in my OnResume method before setting the MainPage. My OnResume now looks like this:

protected override void OnResume()
{
    base.OnResume();

    Task.Delay(10).Wait();

    bool isRegistered = _authenticationService.IsRegistered();

    MainPage = isRegistered 
        ? new NavigationPage(new LoginPage()) 
        : new NavigationPage(new RegisterPage());
}

See this bug report for this workaround.



来源:https://stackoverflow.com/questions/35892598/app-resuming-results-in-crash-with-formsappcompatactivity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!