0
votes

So, I have a fragment - fragment A - which contains an object - object O - used for setting up TextViews and other elements. To instantiate the fragment I use a static method A.getInstance(O). Object O is serializable so I can send it to the new instance of fragment A through a Bundle by using instance.setArguments and so on.

I retrieve O in the onCreate method of A and setup the fields using O in onViewCreated. Everything works fine until here. After I replace A with another fragment - fragment B - and navigate back from B to A, the arguments Bundle doesn't contain object O anymore and I get NullPointerException. The Bundle itself is not null, but it doesn't contain O.

I use this method to replace fragments:

public void replaceCurrentFragment(Fragment fragment) {
        FragmentTransaction fragmentTransaction = context.getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, fragment).addToBackStack(null).commit();
}

Fragment A is also displayed using the method above.

What am I doing wrong?

1
Do you restore object O only from Fragment#getArgumnets() ? Did you try to save and restore object O from Fragment instance state?Oleh Toder
I'm saving object O in the instance of fragment A during onCreate. The problem is I don't get O the second time I get in onCreate.Ionuț Ciuta
I mean, did you override Fragment#onSaveInstanceState to save your object, and then look for it in Bundle, passed in onCreate(Bundle savedInstanceState)?Oleh Toder
Nope, I did not do that. Is it necessary? I'm currently retrieving the bundle using Fragment#getArguments(). Shouldn't it return the same Bundle every time?Ionuț Ciuta

1 Answers

1
votes

Notice Fragment#onCreate(Bundle savedInstanceState) method. When you first created your Fragment from A#getInstance method, this passed Bundle will be null. You will just extract your O objects from Fragment#getArguments method, like you do.
In order to save your object for future use, override Fragment#onSaveInstanceState and save your O object there (may look like this)

private static final String EXTRA_MY_OBJECT = "com.example.extra_my_object";

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable(EXTRA_MY_OBJECT, mMyObject);
}

And then in Fragment#onCreate you can grab your object from passed Bundle Just like that:

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

    if (savedInstanceState != null) {
        mMyObject = savedInstanceState.getSerializable(EXTRA_MY_OBJECT);
    }
    if (mMyObject == null) {
        //fragment was created for first time probably, or something went wrong
        //try to get your object from getArguments

    }
}