I have an abstract base class for activities which instantiate exactly one fragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer" android:layout_width="match_parent" android:layout_height="match_parent" >
</FrameLayout>
public abstract class SingleFragmentActivity extends Activity {
protected abstract Fragment createFragment();
private Fragment m_fragment;
public Fragment getSingleFragment() { return m_fragment; }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getFragmentManager();
m_fragment = fm.findFragmentById( R.id.fragmentContainer );
Log.d("SingleFragment", "fetching a fragment");
if ( m_fragment == null ) {
Log.d("SingleFragment", "SingleFragment requires creating a new one");
m_fragment = createFragment();
fm.beginTransaction().add( R.id.fragmentContainer, m_fragment ).commit();
} else {
Log.d("SingleFragment", "SingleFragment reusing one from fragment manager");
}
}
}
...plus a simple activity and fragment:
public class LoginActivity extends SingleFragmentActivity {
private static final String TAG = "LOGIN ACTIVITY";
private LoginFragment m_loginFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG,"onCreate");
super.onCreate(savedInstanceState);
m_loginFragment = (LoginFragment) getSingleFragment();
Log.d(TAG,"...login fragment foo = "+m_loginFragment.getFoo());
m_loginFragment.setFoo( "Here's a new foo");
}
@Override
public void onPause() { super.onPause(); Log.d(TAG,"onPause"); }
@Override
public void onDestroy() { super.onDestroy(); Log.d(TAG,"onDestroy"); }
@Override
public void onResume() { super.onResume(); Log.d(TAG,"onResume"); }
@Override
protected Fragment createFragment() {
Log.d(TAG,"createFragment()");
return new LoginFragment();
}
}
public class LoginFragment extends Fragment {
private static final String TAG = "LOGIN FRAGMENT";
private String foo = "not set yet";
public String getFoo() { return foo; }
public void setFoo(String s) { foo = s; }
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
Log.d(TAG,"onCreate");
}
@Override
public void onPause() { super.onPause(); Log.d(TAG,"onPause"); }
@Override
public void onDestroy() { super.onDestroy(); Log.d(TAG,"onDestroy"); }
@Override
public void onResume() { super.onResume(); Log.d(TAG,"onResume"); }
}
If I run this code, and rotate the phone after it launches, I see the following log:
08-07 15:02:51.310: LOGIN ACTIVITY: onCreate
08-07 15:02:51.340: SingleFragment: fetching a fragment
08-07 15:02:51.340: SingleFragment: SingleFragment requires creating a new one
08-07 15:02:51.340: LOGIN ACTIVITY: createFragment()
08-07 15:02:51.340: LOGIN ACTIVITY: ...login fragment foo = not set yet
08-07 15:02:51.340: LOGIN FRAGMENT: onCreate
08-07 15:02:51.340: LOGIN ACTIVITY: onResume
08-07 15:02:51.340: LOGIN FRAGMENT: onResume
08-07 15:02:59.799: LOGIN FRAGMENT: onPause
08-07 15:02:59.799: LOGIN ACTIVITY: onPause
08-07 15:02:59.809: LOGIN FRAGMENT: onDestroy
08-07 15:02:59.809: LOGIN ACTIVITY: onDestroy
08-07 15:02:59.829: LOGIN ACTIVITY: onCreate
08-07 15:02:59.829: LOGIN FRAGMENT: onCreate
08-07 15:02:59.869: SingleFragment: fetching a fragment
08-07 15:02:59.869: SingleFragment: SingleFragment reusing one from fragment manager
08-07 15:02:59.869: LOGIN ACTIVITY: ...login fragment foo = not set yet
08-07 15:02:59.869: LOGIN ACTIVITY: onResume
08-07 15:02:59.869: LOGIN FRAGMENT: onResume
Everything works as expected: rotating the phone causes activity and fragment to be destroyed and recreated; I see the fragment manager restores something, but my question is "what?" The member variable foo is not retained, so what is it that is being restored?