Java.lang.InstantiationException: unable to instantiate class ... no empty constructor

I found topics with similar questions, such as mine, but cannot find the answer I'm looking for so far. my application consists of a FragmentActivity that hosts the ViewPagerAdapter (a child of the FragmentPagerAdapter) with a snippet on each tab. My ViewPagerAdapter is being created in the OnCreateView function of parent activity

 _adapter = new ViewPagerAdapter(getApplicationContext() , getSupportFragmentManager() , numOfTabs , status); 

ViewPagerAdapter implements the minimum required methods getItem , getCount and getItemPosition

My getItem initializes a different fragment for each position:

  @Override public Fragment getItem(int position) { Fragment f = new Fragment(); Log.d("Adbox",String.format("Inside ViewPagerAdapter.getItem(%s)",position)); switch(position) { case 0: Log.d("Adbox","All offers =="); f=FragmentAllOffers.newInstance(_context); f.setRetainInstance(true); break; case 1: Log.d("Adbox","Nearby offers =="); f=FragmentNearbyOffers.newInstance(_context); //f.setRetainInstance(true); break; case 2: Log.d("Adbox","My coupons =="); f=FragmentCoupons.newInstance(_context); f.setRetainInstance(true); break; case 3: Log.d("Adbox","Account =="); f=FragmentAccount.newInstance(_context); f.setRetainInstance(true); //f=LayoutLocal.newInstance(_context); break; case 4: Log.d("Adbox","Preferences =="); f=FragmentPreferences.newInstance(_context); f.setRetainInstance(true); break; default: break; } return f; } 

The call to setRetainInstance(true) was added to my efforts to solve the problem that I encountered, but also did not help.

Finally, each of the above fragments implements the public static function newInstance () with the application context as an argument. For example, FragmentNearbyOffers contains the following:

  public static android.support.v4.app.Fragment newInstance(Context ctx) { FragmentNearbyOffers f = new FragmentNearbyOffers(); ctx = context; //Bundle bdl = new Bundle(); return f; } 

Another important piece of information is that parent activity is declared as singleInstance, and I would like it to be so for some reason.

Everything works fine, but at some point, when the activity is in the background for a while, and I try to return to it either through the TaskManager, or by clicking on the application icon, I get an exception

 android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1: make sure class name exists, is public, and has an empty constructor that is public 

The class name definitely exists, it is publicly available and does not have a constructor that looks like an empty one. I even added an empty constructor explicitly, but that didn't help either, although I confirmed that it was being called.

From what I understood from the various posts here, is that Android, when resuming the application, places new instances of fragments in the FragmentPagerAdapter that are not related to the original action. I also confirmed this because when I call getActivity from within the fragment, I get null .. But I donโ€™t understand why I get this exception because there is an empty constructor ... I donโ€™t even know where to fix it, since the execution is included in onCreate activity, and then immediately goes into empty fragment constructors, and then I get an exception. Any other fragment methods, i.e. onAttach, onCreate, etc. not called at all. So it seems that this is really a failure when building fragments.

I attach the whole stacktrace that I get just in case this helps:

  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.advisor/com.advisor.AdBoxWidgetConfigurationFragment}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1: make sure class name exists, is public, and has an empty constructor that is public at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135) at android.app.ActivityThread.access$700(ActivityThread.java:140) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4921) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794) at dalvik.system.NativeStart.main(Native Method) Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.advisor.FragmentNearbyOffers$1: make sure class name exists, is public, and has an empty constructor that is public at android.support.v4.app.Fragment.instantiate(Fragment.java:399) at android.support.v4.app.FragmentState.instantiate(Fragment.java:97) at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1760) at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:200) at com.advisor.AdBoxWidgetConfigurationFragment.onCreate(AdBoxWidgetConfigurationFragment.java:60) at android.app.Activity.performCreate(Activity.java:5206) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074) ... 11 more Caused by: java.lang.InstantiationException: can't instantiate class com.advisor.FragmentNearbyOffers$1; no empty constructor at java.lang.Class.newInstanceImpl(Native Method) at java.lang.Class.newInstance(Class.java:1319) at android.support.v4.app.Fragment.instantiate(Fragment.java:388) 
+4
source share
2 answers

Pay attention to $1 at the end of the error. This is a reference to an anonymous class, not a fragment called FragmentNearbyOffers :

Unable to instantiate fragment com.advisor.FragmentNearbyOffers $ 1

Because fragments require a default constructor, and anonymous classes can never provide one, fragments should always be a named class. The Java Language Specification, Section 15.9.5.1 states:

An anonymous class cannot have an explicitly declared constructor.

This section also explains that constructors are automatically generated according to the context in which the anonymous class is declared. All of these constructors have parameters, so they have a different signature than the default constructor. The combined effect is that anonymous classes can never have a constructor that matches the default constructor value.

You can declare a fragment class in your own file or declare it as a static nested class :

  public static class NestedFragment extends BaseFragment { ... 

Both of these methods should work fine.

+7
source

I managed to solve the problem. This was rather difficult because the error message was misleading. Inside my snippet, I had another nested snippet that I created at runtime with the inner class.

  mMapFragment = new SupportMapFragment() { @Override public void onResume() { // TODO Auto-generated method stub super.onResume(); //initMap(); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); map = mMapFragment.getMap(); if (map != null) { // map.setMapType(GoogleMap.MAP_TYPE_NONE); map.setMyLocationEnabled(true); CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(lat, lng)); zoom = CameraUpdateFactory.zoomTo(18); map.moveCamera(center); map.animateCamera(zoom); } } }; 

Since after the application was killed by Android, when resuming it back, the android recreates the fragments, and I assume that it could not recreate the nested one, because the constructor of the inner class was not visible. I moved the class to a separate file, as suggested in some other posts, and it worked.

+2
source

Source: https://habr.com/ru/post/1479934/


All Articles