0

SITUATION:

An application with resources for portait and landscape, has a simulator that I keep after configuration changes (the user can switch orientation while the simulation is running).

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Installer.installApkData(this);

    simulator = new Simulator(this);
    MainActivity prevActivity = (MainActivity)getLastCustomNonConfigurationInstance();
   if(prevActivity!= null) { 
       // So the orientation did change
       // Restore some field for example
       this.simulator = prevActivity.simulator;
       //this.mNavigationDrawerFragment = prevActivity.mNavigationDrawerFragment;
       //this.mTitle = prevActivity.mTitle;
       Log.d("APP","Activity restarted: simulator recreated");
   }

    requestWindowFeature(Window.FEATURE_PROGRESS);
    setContentView(R.layout.activity_main);
    setProgressBarVisibility(true);

    mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
            .findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));

}


@Override
public Object onRetainCustomNonConfigurationInstance() {
    //restore all your data here
    return this;
}
...

There is a method in the activity that changes the selected section in the NavigationDrawer, in the UI thread because if not it crashes.

public void showHud() {
    // TODO Auto-generated method stub
    runOnUiThread( new Runnable() {
        public void run() {
            mNavigationDrawerFragment.select(1);
            onSectionAttached(2);
            restoreActionBar();
        }
    });
}

This method is used to go directly to display the simulation once the simulator has been connected.

PROBLEM:

All this system works except for when I connect the simulator after switching the orientation. It executes the runOnUiThread but it does nothing. I think the reason for that is that it loses the UI thread that created that view when the activity is restarted.

As you can see there are two lines commented in the reloading of the simulator where I also tried to save the NavigationDrawer object without success in the test: same behavior.

I also tried to save the prevActivity and in the method showHUD(), first asking if its null and if not, execute the method inside the prevActivity. Expecting that it will access the original UI Thread, but I was mistaken.

Is there any solution to keep this UI Thread during the restarting of an activity? or maybe another type of solution?

Thanks a lot.

XaviGG
  • 171
  • 2
  • 19

3 Answers3

0

You should be checking your onSavedInstanceState in your Activity. This is how the Android OS is designed to handle this. You are trying to do this yourself, when you should be relying on the OS supplied functionality.

Quite a few examples of this (if you search SO):

Android: Efficient Screen Rotation Handling

Handle screen rotation without losing data - Android

Community
  • 1
  • 1
Booger
  • 18,579
  • 7
  • 55
  • 72
  • I changed to use the official solution (Retaining a fragment). It works with exactly the same behavior than before: the data is kept but the method executed in UI thread does nothing. – XaviGG May 09 '14 at 07:29
0

If you want to save configuration, you need to save specific things. You can do this in the onPause() or on onSaveInstanceState().

If onCreate() is called after your configuration change, you can get what you need back out of the bundle. when you get it back out, you can then set what you need.

See this: http://developer.android.com/training/basics/activity-lifecycle/recreating.html

0

I am correctly retaining the data object but after a device rotation the function in UI thread has no effect, a function to change the selected section in the NavigationDrawer. I thought it was because I was losing the correct UI thread but actually, what I was losing is this NavigationDrawerFragment.

Just by adding the setRetainInstance(true) line in the OnCreate() of the NavigationDrawerFragment solves the problem:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    ...
XaviGG
  • 171
  • 2
  • 19