Attempt to refresh fragment gives me NullPointerEx

2019-09-12 04:17发布

问题:

I am currently trying to implement code in my android project where my fragments will refresh after a button is pressed, recreating the view and displaying different items. I made sure there were no compatibility issues between android.app and android.support.v4.app, and am positive that I have my fragments' id's labelled correctly.

Here is the exact error I received when running my app on an emulator:

  java.lang.NullPointerException: Attempt to write to field 'int      android.support.v4.app.Fragment.mNextAnim' on a null object reference
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:722)
        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:5257)
        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:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

And here is the java code that is causing the issue in its class:

package edu.sbu.cs.android.NMR.core;
import edu.sbu.cs.android.NMR.core.ImageAdapter;
import edu.sbu.cs.android.R;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class HomeFragment extends Fragment {
     public interface OnSelectedListener {
           public void onSelected();
      }
    OnSelectedListener mListener;
     @Override
       public void onAttach(Activity activity) {
           super.onAttach(activity);
      try {
           mListener = (OnSelectedListener) activity;
       } catch (ClassCastException e) {
           throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
       }
   }

GridView gridview;
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
     Bundle savedInstanceState) {

  View rootView = inflater.inflate(R.layout.fragment_home, container, false);
  gridview = (GridView)rootView.findViewById(R.id.gridView1);
    gridview.setAdapter(new ImageAdapter(gridview.getContext()));
    gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            ((MainActivity) getActivity()).setProblem(position);
            switch (position) {
                case 0:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr0.html");
                    getArguments().putString("problem", "0");
                    FragmentManager fragMan;
                    fragMan = getFragmentManager();
                    Fragment frg= fragMan.findFragmentById(R.layout.fragment_spectra);
                    Fragment frg2 = fragMan.findFragmentById(R.layout.fragment_questions);
                    final FragmentTransaction ft = fragMan.beginTransaction();
                    ft.detach(frg);
                    ft.attach(frg);
                    ft.detach(frg2);
                    ft.attach(frg2);
                    ft.commit();

                case 1:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr1.html");
                    getArguments().putString("problem", "1");
                    fragMan = getFragmentManager();
                    frg = fragMan.findFragmentById(R.layout.fragment_spectra);
                    frg2 = fragMan.findFragmentById(R.layout.fragment_questions);
                    final FragmentTransaction ft2 = fragMan.beginTransaction();
                    ft2.detach(frg);
                    ft2.attach(frg);
                    ft2.detach(frg2);
                    ft2.attach(frg2);
                    ft2.commit();
                case 2:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr2.html");
                    getArguments().putString("problem", "2");
                    fragMan = getFragmentManager();
                    frg = fragMan.findFragmentById(R.layout.fragment_spectra);
                    frg2 = fragMan.findFragmentById(R.layout.fragment_questions);
                    final FragmentTransaction ft3 = fragMan.beginTransaction();
                    ft3.detach(frg);
                    ft3.attach(frg);
                    ft3.detach(frg2);
                    ft3.attach(frg2);
                    ft3.commit();
                default:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr0.html");
            }

            Toast.makeText(getActivity(), " " + position, Toast.LENGTH_SHORT).show();
        }
    });
  return rootView;
   }
}

Has anyone every had this issue before where the problem wasn't due to compatibility between android.support.v4.app and android.app, or am I missing a point in my code where I am making a null object reference? I've searched these forums for weeks and have tried every solution I can think of. I've even switched out ActionBar tabs in my MainActivity for a material design SlidingTabLayout to get rid of the compatibility issue, but it has done nothing. I'm frustrated as to why my code won't, and although I've been working with android for a year, there are still things that I don't quite understand although I've made a different app that works fine. This one is a bit more complex and was passed to me to work on, so I am still figuring out how some of it works. I'm sorry to have gone off on a rant, but I've been stuck on this issue for a while and seem to be at a dead end. Anyone have any solutions?

Also, I'm using android studio to develop my app if that makes any difference in solving the issue, but I had been previously using eclipse and had moved the project over.

回答1:

The problem is that you are using android.support.v4.app.FragmentTransaction on Fragments that are likely extending android.app.Fragment

You have to use android.app.FragmentTransaction with android.app.Fragment and you have to use android.support.v4.app.FragmentTransaction to make transactions involving android.app.v4.app.Fragment

You can't intermix the two. The way to fix it would simply be to change the offending Fragments to extend android.support.v4.app.Fragment instead.



回答2:

Update: In the switch statement, you are missing the break; statements on your cases.

A glance at line 722 of the source code for BackStackRecord suggests you called FragmentTransaction.detach() with a null fragment. Probably one of your calls to findFragmentById() is returning null. To find out which one, check the result of each call and log a debug message if it is null.



回答3:

The Error is clearly showing you that it's acted on null object reference, which means no fragment with the corresponding id in that fragment manager.Try either getChildFragmentManager() or getParentFragment() which worked for me.