Non-stationary inner classes contain a reference to their parent classes. The problem with creating the inner Fragment non-static class is that you always keep a reference to the Activity. GarbageCollector cannot collect your activity. Thus, you can skip an action if, for example, orientation changes. Because the Fragment can still live and is inserted into a new action.
EDIT:
Since some people asked me about an example, I started writing one, doing this, I found a few more problems when using non-static fragments:
- They cannot be used in an XML file because they do not have an empty constructor (they can have an empty constructor, but you usually create non-static nested classes by doing
myActivityInstance.new Fragment() , and this is different from calling only an empty constructor) - They cannot be reused at all, since the
FragmentManager sometimes calls this empty constructor. If you have added a fragment to any transaction.
So, to make my work example, I had to add
wrongFragment.setRetainInstance(true);
The line will not cause the application to crash when changing orientation.
If you execute this code, you will have activity with some text images and two buttons - buttons increase some counter. And the Fragments show what orientation they consider their activity. In the beginning, everything works correctly. But after changing the orientation of the screen, only the first fragment works correctly - the second still causes the material when it is old.
My Activity class:
package com.example.fragmenttest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.content.res.Configuration; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class WrongFragmentUsageActivity extends Activity { private String mActivityOrientation=""; private int mButtonClicks=0; private TextView mClickTextView; private static final String WRONG_FRAGMENT_TAG = "WrongFragment" ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int orientation = getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_LANDSCAPE) { mActivityOrientation = "Landscape"; } else if (orientation == Configuration.ORIENTATION_PORTRAIT) { mActivityOrientation = "Portrait"; } setContentView(R.layout.activity_wrong_fragement_usage); mClickTextView = (TextView) findViewById(R.id.clicksText); updateClickTextView(); TextView orientationtextView = (TextView) findViewById(R.id.orientationText); orientationtextView.setText("Activity orientation is: " + mActivityOrientation); Fragment wrongFragment = (WrongFragment) getFragmentManager().findFragmentByTag(WRONG_FRAGMENT_TAG); if (wrongFragment == null) { wrongFragment = new WrongFragment(); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add(R.id.mainView, wrongFragment, WRONG_FRAGMENT_TAG); ft.commit(); wrongFragment.setRetainInstance(true);
Note that you probably shouldn't onAttach activity on onAttach if you want to use your fragment in different actions, but here it works as an example.
Activity_wrong_fragement_usage.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".WrongFragmentUsageActivity" android:id="@+id/mainView"> <TextView android:id="@+id/orientationText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" /> <TextView android:id="@+id/clicksText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" /> <fragment class="com.example.fragmenttest.WrongFragmentUsageActivity$CorrectFragment" android:id="@+id/correctfragment" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
Simon Meyer Mar 22 '13 at 17:19 2013-03-22 17:19
source share