Android 碎片';s getView()在OnClickListener回调中返回null

Android 碎片';s getView()在OnClickListener回调中返回null,android,android-fragments,android-lifecycle,android-support-library,Android,Android Fragments,Android Lifecycle,Android Support Library,我正在使用支持库,我有一个片段(我将称之为“MyFragment”),它实现了一个在OnClick事件期间由片段的一个视图调用的方法。OnClickListener是在 OnActivityCreate方法如下: @Override public void onActivityCreated(Bundle inState) { super.onActivityCreated(inState); ViewGroup base = (ViewGroup) getView();

我正在使用支持库,我有一个片段(我将称之为“MyFragment”),它实现了一个在OnClick事件期间由片段的一个视图调用的方法。OnClickListener是在 OnActivityCreate方法如下:

@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
        }
    });
}
其中showStuff()触发片段视图中的更改,简单到更新项目的可见性:

private void showStuff() {  //MyFragment:95
    ViewGroup base = (ViewGroup) getView();
    LinearLayout ll = (LinearLayout) base.findViewById(R.id.someview); // MyFragment:97
    ll.setVisibility(View.VISIBLE);
}
在我的测试中一切正常,我的大多数用户也是如此,但我今天收到了来自Google Play开发者控制台的一份ANR报告,报告称该应用程序因在线出现NullPointerException的用户而崩溃:

LinearLayout ll = (LinearLayout) base.findViewById(R.id.someview);
这意味着:

ViewGroup base = (ViewGroup) getView();
返回null。以下是报告:

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)
我已经解决了这个问题(或者我认为是这样,因为我没有复制的方法…),我只是用一个:

if(base != null) {
}
我最好的猜测是,在MyFragment上调用了onDestroyView之后,就安排了回调,从而导致getView()返回null

尽管如此,我还是对这个bug感到困惑,所以我希望您能对这个问题有一些见解:

  • 假设我的hypotesys是正确的,那么在没有布局的情况下执行OnClick回调是正常的,还是我可以将这种行为视为一个bug(老实说:当我单击它时,视图显然在那里,为什么它会在我身上消失)

  • 这个问题是否与我正在使用支持库(最新版本,2013年5月13日)有关

  • 如果这不是一个bug,我遗漏了一些东西,你能给我指一下相关的文档吗


  • 谢谢你的关注

    在姜饼之前,
    视图
    单击机制中存在一个缺陷,即当
    视图
    窗口
    分离时,执行单击的回调未从消息队列中删除。这已在ICS(或蜂窝)中固定。因此,如果您支持姜饼或更低版本,并且您的单击侦听器访问在分离
    视图时删除的其他引用,那么您也应该确保在分离时删除您的单击侦听器


    请注意,这适用于所有类型的单击侦听器,而不仅仅是
    OnClickListener
    。但是,它不适用于长单击侦听器,因为它们的回调从一开始就被正确删除了。

    您使用
    ViewGroup
    代替
    View
    的原因是什么?您还可以检查
    R.id.someview
    是否在
    getView()
    返回的视图中定义了
    R.id.someview
    吗?在这种特殊情况下不是这样,但是我知道布局是ViewGroup的一个子类(否则Java会抛出ClassCastException)。至于R.id.someview,如果找不到相应的视图,那么会在第98行(而不是第97行)抛出异常。你是对的,我完全错过了。nop:谢谢你,
    onActivityCreated()
    回调是针对
    MyFragment
    的,对吗?另外,
    onActivityCreated()
    中使用的
    base
    变量是…?这与问题完全匹配(遗憾的是,我在开发相关应用程序时没有发现这一点…:):你能为这个问题提供一些权威的来源吗?那我就把你的答案标为答案。谢谢,我不知道有任何关于这方面的旧错误报告可供参考,但最权威的来源是;)我明白了:粗略地看,问题出在第5843行(缺少“removeTapCallback”),当窗口失去焦点时。干得好,真的!非常感谢。实际上,真正的修复方法是在第9796行,在
    OnDepachedFromWindow()回调函数中的其他回调函数中包含了
    removePerformClickCallback()
    。我链接到了diff的这一部分,但它只有在页面完全加载时才会跳转到该部分。欢迎你——即使你通过投票并接受我的回答,让我在通过无名英雄徽章寻找寻宝者帽子的过程中倒退了一步:)