6

Ho un'app Xamarin Form, attualmente in fase di sviluppo per Android. Ho un MainActivity utilizzato per estendere FormsApplicationActivity, ma poiché voglio utilizzare un tema personalizzato, ho dovuto modificarlo per estendere FormsAppCompatActivity (vedere la mia altra domanda: Xamarin Forms custom theme not working).Ripristino dell'app in crash con FormsAppCompatActivity

Da quando si passa da FormsApplicationActivity a FormsAppCompatActivity, l'app si arresta in modo anomalo ogni volta che si esce dall'app e quindi si torna all'app. Si genera un errore nella classe App.xaml.cs nel metodo OnResume, dove cerco di impostare la MainPage a una nuova pagina di navigazione:

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

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

L'errore che sto ottenendo è:

java.lang .IllegalStateException: non è possibile eseguire questa azione dopo onSaveInstanceState

questa è la 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

Sembra che questo sia un bug di Android in frammenti e la libreria di supporto. Dai un'occhiata a questo post del blog: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html. Potresti essere applicato a una delle soluzioni da lì. Si noti inoltre che in quel blog si riferiscono al ciclo di vita Android 'Activity' e non all'app Xamarin Forms'. Avresti bisogno di provare quelle modifiche su Android in particolare. – dylansturg

risposta

1

ho risolto con l'aggiunta di un sonno filo nel mio metodo onResume prima di impostare il MainPage. Il mio onResume ora assomiglia a questo:

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

    Task.Delay(10).Wait(); 

    bool isRegistered = _authenticationService.IsRegistered(); 

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

Vedi this bug report per questa soluzione.

+0

c'è anche un post sul forum con ulteriori discussioni sulla soluzione https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity – Korayem

1

Ho avuto il problema simile. Ci sono alcuni punti a riguardo:

1) Spostare il codice di impostazione MainPage nel costruttore dell'app. Come MainPage deve essere impostato nel metodo OnCreate.

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

2) È necessario impostare la pagina di root prima finisce OnCreate. Poiché non conosci la pagina che ti serve, puoi semplicemente impostare la pagina bianca.

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

3) Se questo non aiuta. È sufficiente aggiungere il blocco try/catch al blocco del setter MainPage. Questa è una soluzione sporca, ma funziona. In AppCompatActivity xamarin utilizza Fragments not Views. L'arresto si verifica, quando Android tenta di ripristinare lo stato del frammento. Su Android normale usavamo CommitAllowingStateLoss().

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