Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException when showing a ViewPager a second time

I am using a ViewPager fragment which has two fragments as children. This works great, however when I replace the ViewPager fragment by another fragment and replace this fragment by the ViewPager fragment my application crashes with the following NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
    at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:667)
    at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211)
    at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1319)
    at android.view.View.dispatchRestoreInstanceState(View.java:13756)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2888)
    at android.view.View.restoreHierarchyState(View.java:13734)
    at android.support.v4.app.Fragment.restoreViewState(Fragment.java:468)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1094)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5294)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

My ViewPager fragment consists of the following source code instanciating the two child fragments in case they are null. Furthermore, the ViewPagerAdapter implementation is instanciated and assigned to the ViewPager.

public class ConnectionPasswordViewPagerFragment extends Fragment
{
    private ViewPager vpConnectionPassword;
    private ConnectionPasswordViewPagerAdapter paConnectionPassword;
    private ConnectionPasswordGeneratorMACAddress passwordGeneratorMACAddress;
    private ConnectionPasswordGeneratorSerialNumber passwordGeneratorSerialNumber;

    public ConnectionPasswordViewPagerFragment()
    {
    // Required empty public constructor
    }

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

    if ((this.passwordGeneratorSerialNumber == null) && (this.passwordGeneratorMACAddress == null))
    {
        this.passwordGeneratorMACAddress = new ConnectionPasswordGeneratorMACAddress();
        this.passwordGeneratorSerialNumber = new ConnectionPasswordGeneratorSerialNumber();
    }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState)
    {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_connection_password_view_pager, container, false);
    }

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

    /*if (this.paConnectionPassword == null)
    {*/
        this.paConnectionPassword = new ConnectionPasswordViewPagerAdapter(this.getChildFragmentManager(), this.getActivity(), this.passwordGeneratorMACAddress, this.passwordGeneratorSerialNumber);
    //}
    this.vpConnectionPassword = (ViewPager) this.getActivity().findViewById(R.id.vpConnectionPassword);
    this.vpConnectionPassword.setAdapter(this.paConnectionPassword);
    }
}

The ViewPagerAdapter shown below implementation keeps the reference to the child fragments in an ArrayList and implements the metods getItem(), getCount() as well as getPageTitle(). The class ViewPagerFragment simply extends the support Fragment class and provides the abstract method getPageTitleStringID() implemented by the child fragments.

public class ConnectionPasswordViewPagerAdapter extends FragmentStatePagerAdapter
{
    private static final byte NUMBER_OF_FRAGMENTS = (byte) 2;

    private ArrayList<ViewPagerFragment> childFragments;
    private Activity displayActivity;

    public ConnectionPasswordViewPagerAdapter(FragmentManager fragmentMgm, Activity displayAct, ConnectionPasswordGeneratorMACAddress generatorMACAddress, ConnectionPasswordGeneratorSerialNumber generatorSerialNumber)
    {
    super(fragmentMgm);

    this.childFragments = new ArrayList<>(ConnectionPasswordViewPagerAdapter.NUMBER_OF_FRAGMENTS);
    this.setDisplayActivity(displayAct);
    if (generatorMACAddress != null)
    {
        this.childFragments.add(generatorMACAddress);
    }
    if (generatorSerialNumber != null)
    {
        this.childFragments.add(generatorSerialNumber);
    }
    }

    public Activity getDisplayActivity()
    {
    return this.displayActivity;
    }

    public void setDisplayActivity(Activity value)
    {
    this.displayActivity = value;
    }

    @Override
    public Fragment getItem(int position)
    {
    return this.childFragments.get(position);
    }

    @Override
    public int getCount()
    {
    return ConnectionPasswordViewPagerAdapter.NUMBER_OF_FRAGMENTS;
    }

    @Override
    public CharSequence getPageTitle(int position)
    {
    return this.getDisplayActivity().getString(this.childFragments.get(position).getPageTitleStringID());
    }
}

Thanks for your help!

like image 979
Lukas Avatar asked Mar 02 '16 15:03

Lukas


People also ask

What could be the reason if you are getting NullPointerException?

What Causes NullPointerException. The NullPointerException occurs due to a situation in application code where an uninitialized object is attempted to be accessed or modified. Essentially, this means the object reference does not point anywhere and has a null value.

How do I get rid of NullPointerException?

In Java, the java. lang. NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object. This error can be resolved by using a try-catch block or an if-else condition to check if a reference variable is null before dereferencing it.


2 Answers

I fixed the issue by simply creating the fragment containing the view pager every time I call the support fragment manager's replace method.

public void onSwitchToConnectionPasswordGenerator(View clickedView)
{
    this.fragConnectionPassword = new ConnectionPasswordViewPagerFragment();
    this.getSupportFragmentManager().beginTransaction().replace(R.id.flFragmentContainer, this.fragConnectionPassword).commitAllowingStateLoss();
}
like image 65
Lukas Avatar answered Oct 08 '22 23:10

Lukas


I think your Viewpager is in Fragment, and this fragment have setRetainInstance set to true (i have this error too when i try to retain the parent fragment)

like image 42
Pauland Avatar answered Oct 08 '22 23:10

Pauland