Reputation: 113
I have seen other people running to a similar issue but my case is a bit different. I am not sure if it is a MVVMCross issue or if there is something wrong with the Androind.Support.V4 library. I am using Xamarin Studio.
I have an activity that manages the FragmentDialog.
In my OnCreate method, I check to see if an existing DialogFragment is being shown. This is for the case when a DialogFragment is already opened and a rotation occurs. On each OnCreate I look for the dialog using the tag I assigned. MVVMCross uses the support library as a part of its MXVFragmentAcitivity. I obtain the FragmentManager using the property SupportFragmenetManager which implement a getter (private setters I believe).
The first time the activity is created, everything works as desired. An already opened dialog would not cause any issue as it is being taken care of in the OnCreate method.
First thing I do is base.OnCreate(bundle).
Issue comes in when I rotate the screen and then try to invoke my dialog.
Based on my debugging and tracing, when the rotation occurs, OnDetroy gets called as expected. I checked to see the state of SupportFragmentManager. At that point it is marked is destroyed.
When the new activity is created using the OnCreate, I check for the SupportFragmentManager and I see that there is a new instance. Makes sense.
I tracked it through OnViewModelSet and OnResume and it is all good.
Once the view is all set, I click on my desired button to invoke the dialog. Same steps to invoke the dialog the first time.
The app crashes on dialog.show(SupportFragmentManager, dialogName);
I can see that the old SupportFragmentManager is being invoked. It does not make sense. I think the activity is reloading the old FragmentManger somehow. Is it possible it is being stored in the bundle and restored at one point. Based on Android documentation OnRestoreInstance occurs before OnResume. As mentioned before, when I check SupportFragmentManager in OnResume, it has a new value.
I am a bit confused. The exception received is: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
Here is a short version of the code I have:
Activity OnCreate:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.session_page_layout);
Window.AddFlags (WindowManagerFlags.KeepScreenOn);
var existingDialog = (ConnectionDialogFragment)SupportFragmentManager.FindFragmentByTag(BLEDialogTagName);
if (existingDialog != null)
existingDialog.ViewModel = Mvx.GetSingleton<IDeviceList>() as DeviceListVM;//Mvx.IocConstruct<DeviceListVM> ();
}
FragmentDialog OnCreateDialog:
public override Dialog OnCreateDialog(Bundle savedState)
{
base.EnsureBindingContextSet(savedState);
var view = this.BindingInflate(Resource.Layout.DeviceListView, null);
var dialog = new AlertDialog.Builder(Activity);
dialog.SetTitle(title);
dialog.SetView(view);
dialog.SetNeutralButton("Close", (s, a) => { Dismiss();});
return dialog.Create();
}
and the invoke from Activity:
private void ShowDeviceDialog()
{
var dialog = new ConnectionDialogFragment ();
//Removed ViewModel setting as it is irrelavent
dialog.Show (SupportFragmentManager, BLEDialogTagName);
}
I appreciate if someone can shed some light on this issue. I have seen similar issue but it seems those are related to rotation and app crashes while the dialog is up. Again, I get no crash when a dialog is up and a rotation occurs. The state of SupportFragmentManager is good and correct in OnCreate. Temporary fix is to lock the screen to an orientation. I am locking it to Portrait until I can figure out the issue.
Upvotes: 1
Views: 731
Reputation: 113
Upon further investigation, I found out that I had registered to an event in OnCreate and I failed to unregister from it when the activity was destroyed. Hence the event-handler would still send messages to the old activity which was destroyed. Adding this in OnDestroy resolved this exception. I tested this on Android 5.
Upvotes: 2