Fragment 生命周期 & 延迟加载

Activity 与 Fragment 生命周期对照

image.png

切换fragment典型代码

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.replace(R.id.fragment_recent, recentFragment);
        transaction.commit();

FragmentTransaction add 和 replace 区别

  • 覆盖原fragment, 添加入一个新fragment后, 原来的fragment仍然存活
  • replace 是先remove掉相同id的所有fragment,然后在add当前的这个fragment
    从性能出发, 推荐使用replace

Fragment延迟加载

ViewPager的预加载问题。ViewPager会默认在当前页面的左右两边至少预加载一个页面以保证ViewPager的流畅性。

由于ViewPager的预加载原因,即使在其它Fragment不可见的情况下也会去进行网络请求加载数据。而如果此时用户根本就没有去滑动ViewPager就退出了应用或者切换到了其他页面。那么对于这个不可见的Fragment中的网络请求既浪费了流量也浪费了手机和服务器的性能。

因此,Fragment中为提供了一个 setUserVisibleHint 方法,这个方法中有一个isVisibleToUser的boolean类型的参数,表示当前的Fragment是否对用户可见,可以根据该参数进行数据加载。

注意:

  • setUserVisibleHint在Fragment的onAttach之前就已经被调用了。
  • ViewPager2中,默认关闭了预加载机制。因此延迟加载也没有任何意义了
  • offScreenPageLimit(1)可进行设置

setMaxLifecycle

Androidx并将androidx版本升级到1.1.0之后setUserVisibleHint 方法已被标记为废弃,我们可以跟紧setMaxLifecycle(@NonNull Fragment fragment, @NonNull Lifecycle.State state) 进行控制

Lifecycle生命周期

  • DESTORYED
  • INITALIZED
  • CREATED
  • STARTERD
  • RESUMED
    (setMaxLifecycle中接收的生命周期状态要求不能低于CREATED,否则会抛出一个IllegalArgumentException的异常)

通过setMaxLifecycle方法可以精确控制Fragment生命周期的状态,如果Fragment的生命周期状态小于被设置的最大生命周期,则当前Fragment的生命周期会执行到被设置的最大生命周期,反之,如果Fragment的生命周期状态大于被设置的最大生命周期,那么则会回退到被设置的最大生命周期。

Lifecycle.State.CREATED

        fragment = TestLifecycleFragment.getInstance(Card.DECK[0], 0)
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        fragmentTransaction.add(R.id.ll_fragment, fragment)
        fragmentTransaction.setMaxLifecycle(fragment, Lifecycle.State.CREATED)
        fragmentTransaction.commit()

该Fragment的生命周期仅仅执行到了onCreate就没再往下执行了。并且Activity中没有加载出来当前Fragment。


假设Fragment已经执行到了onResume,此时再为Fragment设置一个CREATED,会执行onPause->onStop->onDestoryView。也就是回退到了onCreate的状态。

Lifecycle.State.STARTED

Fragment已经执行到了onResume方法再为其设置最大生命周期为STARTED,Fragment执行了onPause方法,也就是生命周期退回到了onStart。

Lifecycle.State.RESUMED
已经执行了onResume后的Fragment,再去设置最大生命周期为RESUMED,不会执行任何代码。

androidx 延迟加载

Androidx 1.1.0版本中的FragmentStatePagerAdapter(@NonNull FragmentManager fm, @Behavior int behavior) 已经帮我们实现了。

behavior

  • BEHAVIOR_SET_USER_VISIBLE_HINT:Fragment改变的时候,setUserVisibleHint方法会被调用,也就是这个参数其实是为了兼容以前的老代码。
  • BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT:只有当前显示的Fragment会被执行到onResume,而其它Fragment的生命周期都只会执行到onStart.

[整理自],吹爆这篇(https://juejin.im/post/5e085dafe51d45580769a1eb#heading-2)

你可能感兴趣的:(Fragment 生命周期 & 延迟加载)