I have an issue where ListFragment.onListItemClick
is called after onDestroyView
. I'm getting lots of error reports in the field (10-20 per day of ~1000 active users), but the only way I found to reproduce it is to hammer the back button while clicking all over the screen. Are hundreds of users really doing this?
This is the trace:
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)
Caused from calling getListView().getItemAtPosition
in MyFragment.onListItemClick
(MyFragment:1290). How can getView
return null during a click handler callback? I also determined the fragment was detached at this stage, isAdded() was false, and getActivity was null.
One workaround would be to replace getListView
with the listView
passed in from the callback
public void onListItemClick(ListView listView, View v, int position, long id)
, but other functions will still need to update other parts of the UI, so this would just move the problem somewhere else.
Instead, I nulled the callback in 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();
}
But I still have this onClick problem in other (non-list) fragments too. How exactly does the framework suppress these callbacks normally when the fragment is removed (eg in onBackPressed -> popBackStackImmediate()
)?
In onDestroyView
, I null out extra views that I created in onCreateView
. Do I need to manually clear every listener I've set like this?
This is a similar issue to the unanswered q: Fragment's getView() returning null in a OnClickListener callback
I'm using setOnRetainInstance(true)
in my fragments, btw.