0

I need to pass a complex object including methods and fields to a Fragment. The complex object implements an Interface IComplexObject which is then called by the Fragment, so in my Fragment the complex object itself is not visible.

For creating Instances of the Fragment I use the following code, inspired by this post:

public class SimpleContentFragment extends Fragment {
    private IComplexObject complexObject;

    protected static SimpleContentFragment newInstance(IComplexObject complexObject) {

        SimpleContentFragment f = new SimpleContentFragment();
        f.complexObject = complexObject;

        return f;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        complexObject.doSomeThings();
    }

}

This generally works like expected, however, in some cases when I try to access complexObject from the Fragment's onCreateView I get a NullPointerException.

I have experienced this Exception only on a few older devices and some Kindle devices.

Any ideas what I am doing wrong? How I can pass the object into my Fragment?

Community
  • 1
  • 1
jeff_bordon
  • 392
  • 4
  • 16

2 Answers2

1

1- make your IComplexObject Parcelable.
see those examples 1, 2 and 3

2- but your object in fragment args

protected static SimpleContentFragment newInstance(IComplexObject complexObject) {

        SimpleContentFragment f = new SimpleContentFragment();

        Bundle args = new Bundle();
        args.putParcelable("key_complexObject", complexObject);
        f.setArguments(args);

        return f;
 }

3- on onCreate() function get your object form args

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

    Bundle bundle = getArguments();
    this.complexObject = bundle.getParcelable("key_complexObject");
}
JafarKhQ
  • 8,676
  • 3
  • 35
  • 45
  • Thanks for the hint, I will try that later! Anyway, I don't understand why my approach above works in most of the cases and only sometimes fails... – jeff_bordon Jul 03 '13 at 11:49
  • What if your complex object contains items that are not parcelable, like listeners? – user3829751 Jun 12 '17 at 15:32
1

It happens because your fragment can completely recreated( for example during orientation change), that's why you have NEW object of fragment with all fields equals null.

Mark your object as Parcelable will not help if you object contains other objects, which classes is not under your control ( e.g. library's classes)

You should look in side of setRetainInstance method. It will help.

Divers
  • 9,531
  • 7
  • 45
  • 88
  • Thanks, Divers. In my Manifest I have . Isn't that equivalent to setRetainInstance? Regarding Parcelable I have not got it working yet... – jeff_bordon Jul 03 '13 at 23:21
  • Not the same, if you said that you complex object sometimes become null. Did you try setRetainInstance? It will help in case of save object of fragment for sure. – Divers Jul 04 '13 at 07:24
  • I have removed orientationChanges from the manifest and added setRetainInstance to the Fragment's constructur. On my test devices this works. However, I was unable to reproduce the NullPointerException sofar, so I will know whether that works after first users upgrade and I don't receive Exception reports via ACRA, I will let you know. – jeff_bordon Jul 04 '13 at 07:56
  • Unfortunately that did not help. I'm getting the same NPEs as before the update, really confusing... – jeff_bordon Jul 05 '13 at 08:01
  • Please give me more information when you got NPE? In which cases? – Divers Jul 05 '13 at 10:38
  • That's my problem, I was unable to reproduce the NPE so far. I have only had this NPE once on my 2.2 test device. All I know that it occurs in the onCreateView where I try to access my complexObject. – jeff_bordon Jul 05 '13 at 14:47
  • I was finally able to reproduce the NPE. After I enabled "Don't keep activities" in the developer options I found out that the Fragment instance is retained on configuration changes (thanks `setRetainInstance`). However, the ComplexObject itself needs to be reinitialized, when the activity is destroyed (e.g. due to low memory) e.g. in `onCreate`. Therefore, it is very helpful to test an app with "Don't keep activities" enabled. – jeff_bordon Jul 11 '13 at 20:06