Search code examples
androidactionbarsherlockandroid-fragmentactivity

SherlockFragment's, rotations and onConfigurationChanged


I have an app with several SherlockFragmentActivities and SherlockFragment. I'm having trouble with supporting rotation and transition between the activities.

In my first SherlockFragmentActivity, I attempt to catch the rotations with this code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState == null) {
        InitializeUI();
        details = new MeetingConnectFragment();
        getSupportFragmentManager().beginTransaction().add(
               R.id.activity_scheduled_meeting_connect, details).commit();      
    } 
}
//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);

    InitializeUI();
    details = new MeetingConnectFragment();
    details.setInfo(cInfo);
    FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
    trans.replace(R.id.activity_scheduled_meeting_details, details);
    trans.addToBackStack(null);
            trans.commit();     
}

private void InitializeUI() {
    setContentView(R.layout.activity_meeting_connect);
    // other stuff cut for brevity
}

Within the MeetinConnectFragment there is a button that will bring up a different activity. If the user rotates the screen while in the 2nd activity, then returns to this activity, the program crashes with the exception:

E/AndroidRuntime(17976): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime(17976):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
E/AndroidRuntime(17976):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
E/AndroidRuntime(17976):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
E/AndroidRuntime(17976):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
E/AndroidRuntime(17976):    at com.level3.connect.meetings.MeetingConnectActivity.onConfigurationChanged(MeetingConnectActivity.java:49)
E/AndroidRuntime(17976):    at android.app.ActivityThread.performConfigurationChanged(ActivityThread.java:3675)
E/AndroidRuntime(17976):    at android.app.ActivityThread.handleActivityConfigurationChanged(ActivityThread.java:3849)
E/AndroidRuntime(17976):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1370)
 E/AndroidRuntime(17976):   at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(17976):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(17976):    at android.app.ActivityThread.main(ActivityThread.java:4921)
E/AndroidRuntime(17976):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(17976):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(17976):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
E/AndroidRuntime(17976):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
E/AndroidRuntime(17976):    at dalvik.system.NativeStart.main(Native Method)

The exception is on the line to commit the change. I've been trying to figure out how to handle this scenario but am not quite there. Help appreciated.


Solution

  • I ended up removing all handling of the configuration / rotation and letting Android handle it In order to do this, I had to remove the code to check if the savedInstanceState was null in onCreate in the Activity. Each time the activity is created, it will re-create the fragment.

    I'll have to run some tests to see if this causes a memory leak - perhaps I need to destroy the old fragment first.