FragmentActivity with ViewPager: crash when changing orientation

Hi guys, I used ViewPager in FragmentActivity. When I change the orientation, I get a failure.

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); context = this; loadInitialData(); setActionBar(); initializeUiComponents(); } private void initializeUiComponents() { // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.pager); } 

My data comes dynamically from the database, and I have to call Sysnctask, which gets the data from the database in onResume (). Here is onPostExecute () for Asynctask.

 protected void onPostExecute(Void result) { mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); mViewPager.setAdapter(mSectionsPagerAdapter); } mSectionsPagerAdapter.notifyDataSetChanged(); } } 

Adding a FragmentAdapterCode:

 public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { // getItem is called to instantiate the fragment for the given page. // Return a DummySectionFragment (defined as a static inner class // below) with the page number as its lone argument. Fragment fragment = new PayeeListSectionFragment(); Bundle args = new Bundle(); args.putInt(PayeeListSectionFragment.ARG_SECTION_NUMBER, position + 1); fragment.setArguments(args); return fragment; } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { return string; } } 

Adding snippet code:

 public class PayeeListSectionFragment extends Fragment { /** * The fragment argument representing the section number for this fragment. */ public static final String ARG_SECTION_NUMBER = "section_number"; public PayeeListSectionFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = null; \\ rootView inflated return rootView; } } 

Used xml:

  <android.support.v4.view.ViewPager xmlns:tools="http://schemas.android.com/tools" android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".PayeeListActivity" > <!-- This title strip will display the currently visible page title, as well as the page titles for adjacent pages. --> <android.support.v4.view.PagerTitleStrip android:id="@+id/pager_title_strip" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" android:background="#33b5e5" android:paddingBottom="4dp" android:paddingTop="4dp" android:textColor="#fff" /> </android.support.v4.view.ViewPager> 

Guys! Please help! I get the following crash when changing orientation:

 06-07 11:01:57.834: E/AndroidRuntime(766): FATAL EXCEPTION: main 06-07 11:01:57.834: E/AndroidRuntime(766): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.walletv2.activity/com.walletv2.activity.PayeeListActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.walletv2.activity.PayeeListActivity$PayeeListSectionFragment: make sure class name exists, is public, and has an empty constructor that is public 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3692) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread.access$700(ActivityThread.java:141) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1240) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.os.Handler.dispatchMessage(Handler.java:99) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.os.Looper.loop(Looper.java:137) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread.main(ActivityThread.java:5041) 06-07 11:01:57.834: E/AndroidRuntime(766): at java.lang.reflect.Method.invokeNative(Native Method) 06-07 11:01:57.834: E/AndroidRuntime(766): at java.lang.reflect.Method.invoke(Method.java:511) 06-07 11:01:57.834: E/AndroidRuntime(766): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 06-07 11:01:57.834: E/AndroidRuntime(766): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 06-07 11:01:57.834: E/AndroidRuntime(766): at dalvik.system.NativeStart.main(Native Method) 06-07 11:01:57.834: E/AndroidRuntime(766): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.walletv2.activity.PayeeListActivity$PayeeListSectionFragment: make sure class name exists, is public, and has an empty constructor that is public 06-07 11:01:57.834: E/AndroidRuntime(766): at android.support.v4.app.Fragment.instantiate(Fragment.java:405) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.support.v4.app.FragmentState.instantiate(Fragment.java:97) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1767) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:208) 06-07 11:01:57.834: E/AndroidRuntime(766): at com.walletv2.activity.PayeeListActivity.onCreate(PayeeListActivity.java:78) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.Activity.performCreate(Activity.java:5104) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 06-07 11:01:57.834: E/AndroidRuntime(766): ... 12 more 06-07 11:01:57.834: E/AndroidRuntime(766): Caused by: java.lang.InstantiationException: can't instantiate class com.walletv2.activity.PayeeListActivity$PayeeListSectionFragment; no empty constructor 06-07 11:01:57.834: E/AndroidRuntime(766): at java.lang.Class.newInstanceImpl(Native Method) 06-07 11:01:57.834: E/AndroidRuntime(766): at java.lang.Class.newInstance(Class.java:1319) 06-07 11:01:57.834: E/AndroidRuntime(766): at android.support.v4.app.Fragment.instantiate(Fragment.java:394) 06-07 11:01:57.834: E/AndroidRuntime(766): ... 19 more 
+6
source share
1 answer

There are a few hints of the following lines:

Called: android.support.v4.app.Fragment $ InstantiationException: failed to instantiate com.walletv2.activity.PayeeListActivity $ PayeeListSectionFragment: make sure the class name exists, is public and has an empty constructor that is public

and

06-07 11: 01: 57.834: E / AndroidRuntime (766): caused by: java.lang.InstantiationException: cannot create an instance of class com.walletv2.activity.PayeeListActivity $ PayeeListSectionFragment; no empty constructor

This suggests that you have added a parameterized constructor to your internal PayeeListSectionFragment class. Unfortunately, this will not work, because Android relies on calling a non-parameterized constructor using reflection to restore the state of the fragment during configuration changes (among other things).

If you want to provide one or more parameters to a fragment, you must connect them to the Bundle and set it as an argument using setArguments(Bundle) . Take a look at the DetailsFragment and CountingFragment in the documentation for an example on how to do this.


This problem may also occur in another situation, which may be less obvious for those who are not too familiar with Java. If your fragment is a nested class, say, some Activity , make sure you declare the inner class static . For example, in the context of the above question, it should be a public static class PayeeListSectionFragment (with emphasis on the static modifier). Thus, the inner class will not refer to the outer class and can have its own life cycle without any dependencies on the outer class. Without a static modifier, a nested class cannot be created without creating an external class, which means that Android will encounter problems when trying to restore its fragment class.

An alternative solution would be to move the inner class to its own .java file. Thus, any external class dependencies are automatically deleted.

+7
source

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