androidandroid-fragmentsnullfragmentorientation-changes

Why is the fragment's setRetainInstance(true) method not working?


I cannot get my Fragment to retain its instance on an orientation change.

Activity Class

public class MyActivity extends Activity
{
   private MyFragment fragment;

   public void onCreate(Bundle savedInstanceState)
   {
       if(savedInstanceState == null)
       {
           fragment = new MyFragment();
       }

       //null pointer exception on this line of code. fragment not being retained. 
       getFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
   } 
}

Fragment Class

public class MyFragment extends Fragment
{ 
    private View view;
    private CustomListViewAdapter adapter;
    public ArrayList<HashMap<String, String>> arrHashMap;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        view = inflater.inflate(R.layout.fragment_screen, container, false);

        if(arrHashMap != null)
        {
            ListView lv = (ListView) view.findViewById(R.id.fragment_lv);
            adapter = new CustomListViewAdapter( (MyActivity)getActivity() , arrHashMap);
            lv.setAdapter(adapter);
            lv.setOnItemClickListener((MyActivity)getActivity());
        }
        else
        {
            /* some code to create arrHashMap variable

            */
            ListView lv = (ListView) view.findViewById(R.id.fragment_lv);
            adapter = new CustomListViewAdapter( (MyActivity)getActivity() , arrHashMap);
            lv.setAdapter(adapter);
            lv.setOnItemClickListener((MyActivity)getActivity());
        }

        return(view);
    }

    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
        setRetainInstance(true);
    }
}

MyFragment is remaining null on an orientation change despite setRetainInstance(true) being set in onActivityCreated. When the MyActivity is created MyFragment is also always recreated. Also, I understand that setRetainInstance(true) is not to be used for UI fragments, however, I am not using the saved adapter or view member variables, I am only reusing the retained arrHashMap variable on an orientation change so I can recreate the adapter and change the UI.


Solution

  • UPDATE: I decided not to use setRetainInstance(true) at all and I solved the problem using the ObjectInputStream and ObjectOutputStream classes and saved the arrHashMap object to a file in the onSaveInstanceState(Bundle outState) method of MyActivity, and retrieved the arrHashMap object from that file in the onRestoreInstanceState(Bundle savedInstanceState) method of MyActivity. I then proceeded to set the adapter with the retrived arrHashMap object.

    As an added note, I changed the arrHashMap instance variable of MyFragment to a static variable so it could be accessed from MyActivity.

    Save Code:

    @Override
    public void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
    
        try
        {
            File f = new File( this.getDir("myDir", Context.MODE_PRIVATE), "arrHashMap");
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(f));
            os.writeObject(MyFragment.arrHashMap);
            os.flush();
            os.close();
        }
        catch(IOException e)
        {
            return;
        }
    }
    

    Restore Code:

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState)
    {
        super.onRestoreInstanceState(savedInstanceState);        
    
        ArrayList<HashMap<String,String>> arrHashMap;
        try
        {
            File f = new File( this.getDir("myDir", Context.MODE_PRIVATE), "arrHashMap");
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(f));
            arrHashMap =  ((ArrayList<HashMap<String, String>>) is.readObject() );
            is.close();
        }
        catch (Exception e)
        {
            arrHashMap = null;
        }
        if(arrHashMap != null)
        {
            ListView lv = (ListView)findViewById(R.id.fragment_lv);
            CustomListViewAdapter adapter = new CustomListViewAdapter(this, arrHashMap);
            lv.setAdapter(adapter);
            lv.setOnItemClickListener(this);
        }
    }