Fragment的坑以及从源码角度分析为什么会重复加载

1.在导入Fragment的包时候,记到导入支持V4的包。

2.getActivity()空指针,有时候在调用getActivity()时,该Fragment已经调用了onDetach()。在pop了Fragment后,该Fragment的异步任务任然在执行,在执行完成后调用了getActivity()。我们应该在onDetach()后取消这些异步任务。或者在Fragment中设置一个Activity的全局变量,在onAttach(Activity actity)中赋值,可以保证在onDetach后该Fragment仍然持有Activity的引用,虽然有引起内存泄露的风险,但异步任务未停止的情况下,本身已经有内存泄露了。

3.Can not perform this action after onSaveInstanceState

离开当前Activity 的情况下,系统会调用onSaveInstanceState()保存当前Activity的数据,状态。直到回到该Activity之前调用Fragment都会抛出异常。一般是其他Activity回调该页面执行事务时出现。

解决方法:

该事物使用commitAllowingStateLoss()方法提交,但有可能导致该次事物提交无效。

4.Fragment重叠异常

在界面重启的情况下,应该先判断saveInstanceState==null或者判断加载的fragment是不是为null,否则页面重启时,Fragment会被保存恢复,导致重复加载。

源码角度分析:在离开页面前会调用onSaveInstanceState()方法保存当前Fragment的状态,在系统恢复时候,视图可见状态没帮我们保存,而Fragment的show()方法是默认的。

在源码中,通过FragmentController来实现保存和恢复。Controller通过控制FragmentHostCallBack来间接控制FragmentMannagerImpl。在FragmentMannagerImpl中通过FragmentMagerState来保存Fragment的状态,通过FragmentStateManager获得FragmentState来重启Fragment,在FragmentState中保存了Fragment的类名等信息。

5.Fragment嵌套的那些坑

 正确使用getFragmentManager()和getChildFragmentManager()

6.未必靠谱的出栈方法remove()

在add()的同时将Fragment加入回退栈,并不能真正加入,依然可以返回到被remove的Fragment,而且是空白页。

如果没有将Fragment加入回退栈,remove就可以正常出栈。

加入的话,需要使用popBackStack()系列的方法才可以正常出栈。


猜你喜欢

转载自blog.csdn.net/qq_38256015/article/details/80674724