我正在使用支持库,并且我有一个 fragment (我将称之为“MyFragment”)实现了在 OnClick 事件期间由 fragment 的 View 之一调用的方法。 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() 触发 Fragment View 中的更改,就像更新项目的可见性一样简单:
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();
返回空值。这是报告:
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 回调是否正常,或者我是否可以将此行为视为错误(老实说:当我点击它时 View 显然存在,它为什么要死在我身上)?
这个问题是否与我使用的支持库(最新版本,2013 年 5 月 13 日)有关?
如果这不是错误并且我遗漏了一些东西,你能指点我相关的文档吗?
感谢您的关注!
最佳答案
在 Gingerbread 之前,View
点击机制中存在一个错误,当 View
从中分离时,执行点击的回调不会从消息队列中删除窗口
。这已在 ICS(或可能在 Honeycomb)中得到修复。因此,如果您支持 Gingerbread 或更低版本,并且您的点击监听器访问在分离 View
时删除的其他引用,那么您应该确保在分离时也删除您的点击监听器。
请注意,这适用于所有类型的点击监听器,而不仅仅是 OnClickListener
。但是,它不适用于长按监听器,因为它们的回调从一开始就被正确删除了。
关于android - Fragment 的 getView() 在 OnClickListener 回调中返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17785388/