2

below is the code which is throwing the error message

"java.lang.illegal state exception:Fragment must be public static class to be properly recreated from instance state "

The below code snippet throwing error only after i included **compile 'com.google.android.gms:play-services-ads:11.8.0'** in build.gradle file, else working fine.

public void selectDate(View view) {
            DialogFragment newFragment = new SelectDateFragment();
            newFragment.show(getFragmentManager(), "DatePicker");
        }

@SuppressLint("ValidFragment")
public class SelectDateFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
            @Override
            public Dialog onCreateDialog(Bundle savedInstanceState) {
                final Calendar calendar = Calendar.getInstance();
                int yy = calendar.get(Calendar.YEAR);
                int mm = calendar.get(Calendar.MONTH);
                int dd = calendar.get(Calendar.DAY_OF_MONTH);
                return new DatePickerDialog(getActivity(), this, yy, mm, dd);
            }
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115

2 Answers2

6

Change this:

@SuppressLint("ValidFragment")
public class SelectDateFragment ...

to this:

public static class SelectDateFragment ...

What's happening here is that the Android framework is trying to "recreate" your Fragment from saved instance state, and it can only do that if a number of things are true. One of the many things that needs to be true is that your Fragment doesn't "need" anything else in order to be instantiated, but all non-static inner classes "need" an enclosing instance of the outer class in order to be instantiated.

If adding the static keyword to your Fragment's class definition causes other problems, you'll have to address those separately. Perhaps your enclosing Activity class has a method you want to call; you can replace e.g.

someActivityCall();

with

MyActivity activity = (MyActivity) getActivity();
activity.someActivityCall();
Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Thanks for the support, it is working fine after changing things to static. since static remains through out the execution and may affect performance, i wanted to check is there any way to overcome this. – Andro Developer Sep 17 '18 at 06:12
  • @androdeveloper static inner classes don’t have any performance impact. You are probably thinking of public static constants, which stick around for the app’s lifetime, but instances of a static class don’t do that. – Ben P. Sep 17 '18 at 15:36
  • Thank you for adding how to resolve non-static method access using `getActivity`! – Prof Feb 21 '21 at 19:29
1

Suppose that if you remove suppress annotation you will get that problem every time (not only when build.gradle changed). In your case, suppose, declaration of SelectDateFragment class is placed inside another class - it's named inner class - and have no static qualifier. So there is restriction for Fragment not to be inner non-static class. To fix problem you need to declare your fragment as public static class (if it's placed inside another class declaration).

ConstOrVar
  • 2,025
  • 1
  • 11
  • 14
  • Thanks i followed the same, it is working fine. since static remains through out the execution and may affect performance, i wanted to check is there any way to overcome this. – Andro Developer Sep 17 '18 at 06:11
  • @AndroDeveloper, what do you mean by _affect performace_? As I know, `static` classes have impact on performance no more than `inner` classes (without `static` qualifier). And there is no way to mark `Fragment` non static inside another class, because in that case android couldn't recreate it's instance (when need it) without instance of outer class . – ConstOrVar Sep 17 '18 at 06:52