我正在使用支持库,我有一个片段(我称之为“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。
尽管如此,我对这个错误感到很困惑,所以我希望你对这个问题有所了解:
假设我的hypotesys是正确的,在没有布局时执行OnClick回调是正常的,还是我可以将此行为视为错误(老实说:当我点击它时,视图显然是存在的,为什么它会死在我身上?)
这个问题是否与我使用支持库(最新版本,2013年5月13日)有关?
如果这不是错误而且我遗漏了什么,请指点相关文档吗?
感谢您的关注!
答案 0 :(得分:1)
直到Gingerbread,View
点击机制中存在一个错误,当View
与Window
分离时,没有从消息队列中删除执行点击的回调。这已在ICS(或可能在Honeycomb)中修复。因此,如果您支持Gingerbread或更低版本,并且您的点击侦听器访问在分离View
时删除的其他引用,那么您应该确保在分离时删除您的点击侦听器。
请注意,这适用于所有类型的点击侦听器,而不仅仅是OnClickListener
。但是它不适用于长按侦听器,因为它们的回调从一开始就被正确删除。