6

Mam aplikację Xamarin Forms, obecnie budowaną na Androida. Mam MainActivity, który był używany do rozszerzania FormsApplicationActivity, ale ponieważ chcę użyć niestandardowego motywu, musiałem go zmienić, aby rozszerzyć FormsAppCompatActivity (zobacz moje inne pytanie: Xamarin Forms custom theme not working).Wznowienie aplikacji powoduje awarię z FormsAppCompatActivity

Od czasu przejścia z wersji FormsApplicationActivity na FormsAppCompatActivity aplikacja ulega awarii po każdej zmianie aplikacji i ponownym uruchomieniu aplikacji. To generuje błąd w klasie App.xaml.cs w metodzie OnResume, gdzie staram się ustawić mainpage do nowej strony nawigacyjnej:

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

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

Błąd Dostaję jest:

java.lang .IllegalStateException: nie można wykonać tę czynność po onSaveInstanceState

to 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

Wygląda na to, że jest to błąd Androida w fragmentach i bibliotece pomocy technicznej. Zobacz ten post na blogu: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html. Możesz się ubiegać o jedno z rozwiązań z tego miejsca. Pamiętaj też, że na tym blogu odnoszą się do cyklu życia "Aktywności" Androida, a nie do aplikacji "Xamarin Forms". Musisz wypróbować te zmiany na Androidzie. – dylansturg

Odpowiedz

1

Rozwiązałem go, dodając snu wątku w mojej metodzie OnResume przed ustawieniem MainPage. Moja OnResume teraz wygląda tak:

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

    Task.Delay(10).Wait(); 

    bool isRegistered = _authenticationService.IsRegistered(); 

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

Zobacz this bug report tego obejścia.

+0

jest tu także wpis na forum z dalszą dyskusją na temat rozwiązania https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity – Korayem

1

Miałem podobny problem. Istnieje kilka punktów na ten temat:

1) Przenieś swój kod ustawień strony głównej do konstruktora aplikacji. Jako, że MainPage powinien być ustawiony w metodzie OnCreate.

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

2) Musisz ustawić stronę główną, zanim zakończy się OnCreate. Ponieważ nie znasz strony, której potrzebujesz, możesz po prostu ustawić stronę blanc.

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

3) Jeśli to nie pomoże. Możesz po prostu dodać blok próbny/catch obfitować w seter MainPage. To jest brudne rozwiązanie, ale działa. W AppCompatActivity xamarin używa fragmentów, a nie widoków. Następuje awaria, gdy Android próbuje przywrócić stan fragmentu. Na zwykłym Androidzie używaliśmy CommitAllowingStateLoss().

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