最近开发一直在使用ListFragment,ListFragment有一个 setListShown(boolean shown)的方法,当传入参数为false的时候,ListFragment显示一个进度条,然后在这段时间时间里面可以异步加载数据,然后等到数据加载完成以后再次调用 setListShown(true),然后隐藏进度条,显示ListView。
但是这个方法必须在 ListView已经创建以后才可以,否则就会抛出一个“Content view not yet created”,也就是 最好调用这个方法是在 OnActivityCreated之后和 OnDestroy之前。最近笔者在使用它的时候因为在 OnActivityCreated 使用了一个 AsyncTask来异步加载数据,但是有时候莫名其妙程序就会挂掉,然后在Log里看到“Content view not yet Created”,各种查资料都没有解决问题,程序还是时不时就挂了不知道,然后留下一个“Content view not yet Created”孤零零地躺在Logcat里面。
后来笔者突然想起来,ListFrament维护的listview在 onCreateView时候被创建,但是在 OnDestroy之后就被销毁了,会不会是因为异步加载数据的时候,当数据加载完成以后,ListFragment已经被Destroy了,所以当在AsyncTask的 doInBackgroud方法(在子先撑)执行完毕之后,onPostExecute里面调用 setListShown的时候,listView已经不存在,所以程序才crash掉呢?
经过测试发现,原因就是这样。
这种情况比较容易出现的情况是ViewPaper和ListFragment混合使用并且ListFramgnt是通过异步加载数据的时候,因为 ViewPaper能缓存的页面数量是有限的(通过ViewPaper.setOffscreenPageLimit(int limit)来控制),当ViewPaper滑动到Limit之外的时候 之前缓存的ListFragment就会被销毁,这个时候 因为之前的ListFragment的AsyncTask已经开始执行,当执行结束的时候 发现 ListView已经销毁,所以再调用 setListShown()的时候,程序就crash了。
解决的办法就是在ListFragment的 onStop方法(onDestroy之前)里面把正在执行的 AsyncTask cancel掉,这样就不会再调用setListShown了。
但是这个方法必须在 ListView已经创建以后才可以,否则就会抛出一个“Content view not yet created”,也就是 最好调用这个方法是在 OnActivityCreated之后和 OnDestroy之前。最近笔者在使用它的时候因为在 OnActivityCreated 使用了一个 AsyncTask来异步加载数据,但是有时候莫名其妙程序就会挂掉,然后在Log里看到“Content view not yet Created”,各种查资料都没有解决问题,程序还是时不时就挂了不知道,然后留下一个“Content view not yet Created”孤零零地躺在Logcat里面。
后来笔者突然想起来,ListFrament维护的listview在 onCreateView时候被创建,但是在 OnDestroy之后就被销毁了,会不会是因为异步加载数据的时候,当数据加载完成以后,ListFragment已经被Destroy了,所以当在AsyncTask的 doInBackgroud方法(在子先撑)执行完毕之后,onPostExecute里面调用 setListShown的时候,listView已经不存在,所以程序才crash掉呢?
经过测试发现,原因就是这样。
这种情况比较容易出现的情况是ViewPaper和ListFragment混合使用并且ListFramgnt是通过异步加载数据的时候,因为 ViewPaper能缓存的页面数量是有限的(通过ViewPaper.setOffscreenPageLimit(int limit)来控制),当ViewPaper滑动到Limit之外的时候 之前缓存的ListFragment就会被销毁,这个时候 因为之前的ListFragment的AsyncTask已经开始执行,当执行结束的时候 发现 ListView已经销毁,所以再调用 setListShown()的时候,程序就crash了。
解决的办法就是在ListFragment的 onStop方法(onDestroy之前)里面把正在执行的 AsyncTask cancel掉,这样就不会再调用setListShown了。