6

Ich habe eine Xamarin Forms App, die derzeit für Android gebaut wird. Ich habe eine MainActivity, die verwendet, um FormsApplicationActivity zu erweitern, aber weil ich ein benutzerdefiniertes Thema verwenden möchte, musste ich es ändern, um FormsAppCompatActivity zu erweitern (siehe meine andere Frage: Xamarin Forms custom theme not working).App, die zum Absturz mit FormsAppCompatActivity führt

Seit dem Wechsel von FormsApplicationActivity zu FormsAppCompatActivity stürzt die App ab, wann immer ich aus der App ausschalte und dann zurück in die App. Es wirft einen Fehler in der App.xaml.cs Klasse in der OnResume Methode, wo ich versuche, die Mainpage auf eine neue Navigationsseite zu setzen:

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

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

Der Fehler Ich erhalte ist:

java.lang .IllegalStateException: Kann diese Aktion nach nicht durchführen onSaveInstanceState

Dies ist der 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) 
+0

Es sieht aus wie ein Android-Bug in Fragmenten und die Support-Bibliothek. Schauen Sie sich diesen Blog-Beitrag an: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html. Sie könnten sich für eine der Lösungen von dort bewerben. Beachten Sie auch, dass in diesem Blog der Android-Aktivitäts-Lebenszyklus und nicht die Xamarin-Formular-App gemeint ist. Sie müssten diese Änderungen speziell auf Android ausprobieren. – dylansturg

Antwort

1

Ich löste es durch Hinzufügen eines Thread-Schlafes in meiner OnResume-Methode vor dem Festlegen der MainPage. Mein onResume sieht nun wie folgt aus:

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

    Task.Delay(10).Wait(); 

    bool isRegistered = _authenticationService.IsRegistered(); 

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

Siehe this bug report für diese Problemumgehung.

+0

gibt es hier auch einen Forenbeitrag mit weiterer Diskussion über die Lösung https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity – Korayem

1

Ich hatte das ähnliche Problem. Es gibt einige Punkte darüber:

1) Verschieben Sie den MainPage-Einstellungscode in App-Konstruktor. Als MainPage sollte in OnCreate-Methode festgelegt werden.

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

2) Sie müssen Ihre Root-Seite festlegen, bevor OnCreate beendet wird. Da Sie die gewünschte Seite nicht kennen, können Sie einfach die Blank-Seite einstellen.

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

3) Wenn das nicht hilft. Sie können einfach try/catch Block im Überfluss MainPage Setter hinzufügen. Das ist eine schmutzige Lösung, aber es funktioniert. In AppCompatActivity verwendet Xamarin Fragmente, nicht Views. Der Absturz geschieht, wenn Android versucht, den Fragmentstatus wiederherzustellen. Auf normalem Android verwendeten wir CommitAllowingStateLoss().