【发布时间】:2013-09-06 03:22:34
【问题描述】:
我有一个问题,ListFragment.onListItemClick 在onDestroyView 之后被调用。我在现场收到了很多错误报告(大约 1000 个活跃用户每天 10-20 个),但我发现重现它的唯一方法是在单击整个屏幕时敲击后退按钮。成百上千的用户真的在这样做吗?
这是痕迹:
java.lang.IllegalStateException: Content view not yet created
at au.com.example.activity.ListFragment.ensureList(ListFragment.java:860)
at au.com.example.activity.ListFragment.getListView(ListFragment.java:695)
at au.com.example.activity.MyFragment.onListItemClick(MyFragment.java:1290)
at au.com.example.activity.ListFragment$2.onItemClick(ListFragment.java:90)
at android.widget.AdapterView.performItemClick(AdapterView.java:301)
at android.widget.AbsListView.performItemClick(AbsListView.java:1519)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3278)
at android.widget.AbsListView$1.run(AbsListView.java:4327)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
由在 MyFragment.onListItemClick (MyFragment:1290) 中调用 getListView().getItemAtPosition 引起。 getView 如何在单击处理程序回调期间返回 null?我还确定在这个阶段片段被分离,isAdded() 为假,getActivity 为空。
一种解决方法是将getListView 替换为从回调中传入的listView
public void onListItemClick(ListView listView, View v, int position, long id),但其他功能仍需要更新 UI 的其他部分,所以这只会将问题转移到其他地方。
相反,我取消了onDestroyView 中的回调:
public void onDestroyView() {
mHandler.removeCallbacks(mRequestFocus);
if(mList!=null){
mList.setOnItemClickListener(null);
}
mList = null;
mListShown = false;
mEmptyView = mProgressContainer = mListContainer = null;
mStandardEmptyView = null;
super.onDestroyView();
}
但是我在其他(非列表)片段中仍然存在这个 onClick 问题。当片段被移除时(例如在onBackPressed -> popBackStackImmediate() 中),框架究竟如何正常地抑制这些回调?
在onDestroyView 中,我取消了我在onCreateView 中创建的额外视图。我需要手动清除我这样设置的每个侦听器吗?
这与未回答的问题类似:Fragment's getView() returning null in a OnClickListener callback
顺便说一句,我在片段中使用了setOnRetainInstance(true)。
【问题讨论】:
-
可以给片段代码吗?
-
你能发布你的点击代码吗?你在那里做任何背景工作吗?您是否在 onclick 中检查 getView() == null 吗?
-
您的应用支持轮播吗?当您的手机旋转时,当前活动被破坏并创建一个新活动。这意味着如果用户在旋转之前单击了某个项目,则单击将返回,但 Activity 上下文和视图将为空。按照建议检查视图是否不为空,请确保您没有模拟尝试通过旋转访问上下文(因为它已被破坏)。
-
您是否为 OnClickListener 使用静态内部类?作为快速修复,我要做的是覆盖 onBackPressed() 并将所有元素上的 Clickable 设置为 false 或放入一个状态布尔值,如果按下返回,则不执行任何操作。请记住,ClickListener 对它所侦听的元素具有隐式引用,因此即使您 setOnItemClickListener(null),它仍将引用该对象。甚至可能是 OnDestroy 延迟到足以在设置的 null 发生之前被调用。
标签: android android-fragments android-lifecycle