Android必读之Fragment生命周期

Fragment的生命周期是什么?为什么ViewPager中Fragment来回滑动但是onResume没有调用?Activity与Fragment的声明周期有何不同?

Fragment的生命周期

套用一张google的官方图片:
《Android必读之Fragment生命周期》

  1. onAttach(): 完成Fragment和Activity的绑定,参数中的Activity即为要绑定的Activity,可以进行赋值等操作。
  2. onCreate() : 完成Fragment的初始化
  3. onCreateView() : 加载View布局,绑定布局文件
  4. onActivityCreated() : 与Fragment绑定的Activity已经执行完成了onCreate,可以与Activity进行交互操作。
  5. onStart() : Fragment变为可见状态
  6. onResume() : Fragment变为可交互状态
  7. onPause(): Fragment变为不可交互状态(不代表不可见)
  8. onSaveInstanceState():保存当前Fragment的状态。记录一些数据,比如EditText键入的文本,即使Fragment被回收又重新创建,一样能恢复EditText之前键入的文本。
  9. onStop(): Fragment变为不可见状态
  10. onDestroyView() : 销毁Fragment的有关视图,但并未和Activity解绑,可以通过onCreateView()重新创建视图。Fragment销毁时或者ViewPager+Fragment情况下会调用
  11. onDestroy() : 销毁Fragment时调用。
  12. onDetach() : 解除和Activity的绑定。Fragmen销毁最后一步

Activity与Fragment生命周期的区别

《Android必读之Fragment生命周期》
可以十分明了的看到,当Activity处于不同生命周期时Fragment生命周期的流程。需要关注一下两者生命周期顺序问题,其中onCreate、onStart、onResume都是Activity先调用之后才是Fragment,onPause、onStop、onDestroy(在Fragment中是onDetach),是先Fragment调用之后才是Activity。其他的就不展开说了,图十分明了。

Fragment相关操作对生命周期的影响

添加Fragment可以分为静态添加和动态添加两大类。静态添加是在XML中直接添加Fragment,简单方便,缺点是添加之后不能在删除。动态添加是在代码中FragmentManger使用一系列FragmentTransaction事务操作动态控制,灵活多变。一般都是使用动态添加,下面就讲讲动态添加有关的生命周期。

  1. add:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume
  2. remove:onPause->onStop->onDestroyView->onDestroy->onDetach
  3. show:onHiddenChanged(boolean hidden) hidden为false
  4. hide:onHiddenChanged(boolean hidden) hidden为true
  5. replace:旧Fragment的remove生命周期->新Fragment的add生命周期
  6. replace+addToBackStack:onPause->onStop->onDestroyView->新Fragment的add生命周期
    之后点击back:新Fragment的remove,然后旧的Fragment从BackStack(Fragment栈)中恢复:onCreateView->onViewCreated->onActivityCreated->onStart->onResume 就是第一张图的线
  7. detach:onPause->onStop->onDestroyView 可以看到只是视图被移除,Fragment关联状态还是不变,还是处于FragmentManger的管理下
  8. FragmentTransaction.attach(Fragment var1):onStart->onResume->onCreateView
注意:Fragment的show和hide仅仅是将Fragment视图设置为是否可见,不会调用任何生命周期。该Fragment的生命周期还是会随着Activity的生命周期变化而变化,例如FragmentA hide、FragmentB show,点击Home A和B都会onPause->onStop

应用被系统回收对生命周期的影响

应用被回收一般都是后台应用,所以生命周期是从onDestroyView开始

  • 单独一个Fragment
    onDestroyView->onDestroy->onDetach->add生命周期
  • Fragment A hide,Fragment B show
    A.onDestroyView->A.onDestroy->A.onDetach->B.onDestroyView->B.onDestroy->B.onDetach->A.onAttach->A.onCreate->B.onAttach->B.onCreate->A.onCreateView->A.onActivityCreated->B.onCreateView->B.onActivityCreated->A.onStart->B.onStart->A.onResume->B.onResume
为了防止在系统回收应用情况下,再次进不出错,强烈建议大家
1. 使用setArguments(Bundle bundle)方法传递参数。对于常规变量想必大家都已经十分熟练了,就不细说了。这里主要强调View变量和接口变量,View变量可以通过传入View的id,之后再通过id获取view的方法来实现。接口可以通过Activity实现,Fragment强转Activity实现。
2. addFragment之前先通过findFragmentById判断是否添加过避免重复添加,如使用FragmentAdapter可以在onSaveInstanceState存储相应Fragment.getTag

ViewPager对Fragment生命周期的影响

ViewPager+Fragment已经是比较常见的组合,一般搭配ViewPager的FragmentPagerAdapter或FragmentStatePagerAdapter使用。不过ViewPager为了防止滑动出现卡顿,有一个缓存机制,默认情况下ViewPager会创建并缓存当前页面左右两边的页面(如Fragment)。此时左右两个Fragment都会执行从onAttach->….->onResume的生命周期,明明Fragment没有显示却已经到onResume了,然后滑动fragment时又不会调用onResume,onPause,在某些情况下会出现问题。比如数据的加载时机、判断Fragment是否可见等。
那么应该如何处理呢?可以使用一下方法来判断Fragment是否可见

@Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            reportPageShow();
        }
    }

 

点赞

发表评论