简体   繁体   中英

Null pointer exception while communicating between fragments, android studio won't recognize fragment id because it expects resource of type id?

So I've encountered a null pointer exception when trying to pass data between fragments. The error occurs in my main activity, and it's telling me when the updateText method is called on one of my fragments (and both this method and my fragment classes are defined), it's returning a null reference. Here is the error message text in full:

03-01 17:25:13.062    2011-2011/edu.sbu.cs.android E/AndroidRuntime﹕         FATAL EXCEPTION: main
Process: edu.sbu.cs.android, PID: 2011
java.lang.NullPointerException: Attempt to invoke virtual method 'void edu.sbu.cs.android.NMR.core.SpectraFragment.updateText(java.lang.String)' on a null object reference
        at edu.sbu.cs.android.NMR.core.MainActivity.onSelected(MainActivity.java:31)
        at edu.sbu.cs.android.NMR.core.HomeFragment$1.onItemClick(HomeFragment.java:66)
        at android.widget.AdapterView.performItemClick(AdapterView.java:305)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1146)
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:3053)
        at android.widget.AbsListView.onTouchUp(AbsListView.java:3872)
        at android.widget.AbsListView.onTouchEvent(AbsListView.java:3637)
        at android.view.View.dispatchTouchEvent(View.java:8471)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
        at android.view.View.dispatchPointerEvent(View.java:8666)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:143)
        at android.os.Looper.loop(Looper.java:122)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        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.in

Here is the java code where I am having the error

MainActivity class:

@Override
public void onSelected(String text){
    SpectraFragment frag = (SpectraFragment)
            getSupportFragmentManager().findFragmentById(R.layout.fragment_spectra);
    frag.updateText(text);

Here is the relevant code of the two fragments I am trying to pass data between:

Fragment A (Home):

public interface OnSelectedListener {
        public void onSelected(String text);
  }

OnSelectedListener mListener;
  @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
      this.getActivity();
      try {
            mListener = (OnSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnSelectedListener");
        }
    }

@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:                        mListener.onSelected("file:///android_asset/nmr0.html");
                    FragmentManager fragMan;
                    fragMan = getFragmentManager();
                    Fragment frg= fragMan.findFragmentByTag("fragment_spectra");
                    Fragment frg2 = fragMan.findFragmentByTag("fragment_questions");
                    final FragmentTransaction ft = fragMan.beginTransaction();
                    ft.detach(frg);
                    ft.attach(frg);
                    ft.detach(frg2);
                    ft.attach(frg2);
                    ft.commit();

                case 1:
                    mListener.onSelected("file:///android_asset/nmr1.html");
fragMan = getFragmentManager();
                    frg=      fragMan.findFragmentByTag("fragment_spectra");
                    frg2 = fragMan.findFragmentByTag("fragment_questions");
                    final FragmentTransaction ft2 = fragMan.beginTransaction();
                    ft2.detach(frg);
                    ft2.attach(frg);
                    ft2.detach(frg2);
                    ft2.attach(frg2);
                    ft2.commit();
 default:
                        SpectraFragment.w.loadUrl("file:///android_asset/nmr0.html");
            }

Fragment B (Spectra):

public void updateText(String text){
    setStr(text);
    FragmentManager fragMan;
    fragMan = getFragmentManager();
    Fragment frg= fragMan.findFragmentByTag("fragment_spectra");
    final FragmentTransaction ft = fragMan.beginTransaction();
   // ft.detach(frg);
    ft.attach(frg);
    ft.commit();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_spectra, container, false);;
    if (getStr() != null) {
        w.loadUrl(getStr());
    }
    else
    {
        w.loadUrl("file:///android_asset/nmr0.html");
    }
        w.getSettings().setBuiltInZoomControls(true);
    w.getSettings().setDisplayZoomControls(false);
    return rootView;

}

private void setStr (String text){
    str = text;
}

private String getStr (){
    return str;
}

In the android studio editor, it tells me when I call the updateText method in my receiving fragment that it give the message "expected resource of type id" I know this has to do with the R class, and currently my fragment classes are defined as r.layout.fragment_a. Does the problem lie within this reference? Am I not passing the data properly between fragments? I know this has nothing to do with the android.support.v4.app and andoid.app incompability, as I have removed all of those references and got the app to work with that, thanks to Stack Overflow.. I have all the required methods in the right places. What am I doing wrong.?

Edit: Here are my relevant xml files:

XML for MainActivity:

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
<edu.sbu.cs.android.NMR.core.NonSwipeableViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="45dp">

</edu.sbu.cs.android.NMR.core.NonSwipeableViewPager>

    <edu.sbu.cs.android.NMR.adapter.SlidingTabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:background= "#000000"
        android:textColor="#ffffff"
        />

</RelativeLayout>

XML for HomeFragment:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#949494" >

<GridView 
    android:id="@+id/gridView1"
    android:background="#949494" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:columnWidth="35dp"
    android:numColumns="5"
    android:verticalSpacing="5dp"
    android:horizontalSpacing="5dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    android:listSelector="#FFF">


</GridView>

</RelativeLayout>

XML for SpectraFragment:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#949494">

   <WebView
        android:id="@+id/imgView"
        android:background="#949494" 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />
</RelativeLayout>

Edit: Looking at the View Hierarchy, if I am understanding it correctly it looks like I should be referencing android:id content tto get the container of the SpectraFragment as it contains my tabs and fragments. Is that right?

查看层次结构

I believe the issue is because you're attempting to get a fragment by the layout. So, frag is not getting the value of your fragment and is null, thus your null object reference. You should be getting the fragment by the id of the container.

Problem Code:

@Override
public void onSelected(String text){
    SpectraFragment frag = (SpectraFragment)
        getSupportFragmentManager().findFragmentById(R.layout.fragment_spectra);
    frag.updateText(text);
}

Fix:

SpectraFragment frag = (SpectraFragment)
        getSupportFragmentManager().findFragmentById(ID_OF_CONTAINER);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM