简体   繁体   中英

Fragment's getView() returning null in a OnClickListener callback

I'm using the support library and I have a Fragment (I'll call "MyFragment") implementing a method invoked by one of the Fragment's View during an OnClick event. The OnClickListener is set in the OnActivityCreate method like this:

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

    ViewGroup base = (ViewGroup) getView();
    TextView tv = (TextView) base.findViewById(R.id.monografiat);
    tv.setOnClickListener(new OnClickListener() {                            
        @Override
        public void onClick(View v) {
            showStuff(); // MyFragment:150
        }
    });
}

where showStuff() triggers a change in the Fragment's View, something as simple as updating the visibility of an item:

private void showStuff() {  //MyFragment:95
    ViewGroup base = (ViewGroup) getView();
    LinearLayout ll = (LinearLayout) base.findViewById(R.id.someview); // MyFragment:97
    ll.setVisibility(View.VISIBLE);
}

Everything works fine on my tests, and the same can be said about most of my users, however I have received today a single ANR report from Google Play developer's console, stating that the app crashed for a user with a NullPointerException on the line:

LinearLayout ll = (LinearLayout) base.findViewById(R.id.someview);

which means that:

ViewGroup base = (ViewGroup) getView();

returned null. This is the report:

java.lang.NullPointerException
    at mypackage.MyFragment.showStuff(MyFragment.java:97)
    at mypackage.MyFragment.access$0(MyFragment.java:95)
    at mypackage.MyFragment$2.onClick(MyFragment.java:150)
    at android.view.View.performClick(View.java:2538)
    at android.view.View$PerformClick.run(View.java:9152)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)

I have fixed the problem (or so I think, since I don't have a method of reproduction...) by just surrounding the offending lines with a:

if(base != null) {
}

my best guess is that the callback has been scheduled after onDestroyView has been called on MyFragment, thus resulting in getView() returning null.

Still, I'm quite puzzled by this bug, so I'd like your insights on the matter:

  1. assuming that my hypotesys is correct, is it normal for a OnClick callback to be executed when no layout is present, or can I regard this behavior as a bug (honestly: the view was obviously there when I clicked it, why should it die on me)?

  2. Is this problem related to the fact that I'm using the support library (last version, 13 May 2013)?

  3. If it's not a bug and I'm missing something, could you please point me to the relevant documentation?

Thank you for your attention!

Up until Gingerbread there was a bug in the View click mechanism in that the callback for performing the click was not removed from the message queue when the View was detached from the Window . This has been fixed in ICS (or possibly in Honeycomb). Therefore if you're supporting Gingerbread or below, and your click listeners access other references that are removed when the View s are detached, then you should make sure to remove your click listeners upon detachment as well.

Note that this applies to all kinds of click listeners, not just OnClickListener . However it doesn't apply to long click listeners, as their callbacks were removed properly from the beginning.

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