android fragment教程,正确使用android fragment

本文基于com.android.support:support-v4:26.1.0 分析android fragment分析。

fragment目前已经被广泛应用到app开发中,它的使用使得activity角色变为fragment的容器,调度fragment的添加显示和隐藏。fragment作为单独的功能模块,提高的模块化和可复用。

fragment具有使用场景包括:

多个fragment嵌套,点击当前fragment按钮进入下一个fragment

一个activity同时显示多个fragment

viewpager 分页显示多个fragment

但实际使用过程中往往会碰到getActivity()为null 导致app奔溃异常,网路请求回调fragment不存在导致异常奔溃等等恼人的问题。 因为我们需要深入理解fragment的生命周期。

34729546ec9e

PDMCpkV.png

当activity 持有一个fragment时:

点击进入

com.example.wenson.myfragmenttest I/Wen.Activity: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onStart

com.example.wenson.myfragmenttest I/Wen.Activity: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onResume

按back按键返回

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onPause

com.example.wenson.myfragmenttest I/Wen.Activity: onPause

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onStop

com.example.wenson.myfragmenttest I/Wen.Activity: onStop

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onDestroyView

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onDestroy

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onDetach

com.example.wenson.myfragmenttest I/Wen.Activity: onDestroy

从上面的log分析总结:

和activity的交互必须在onActivityCreated执行之后调用,比如getContext(),getActivity()。

当在fragment执行异步请求回调时 比如网络请求时,如果需要UI更新时需要判断fragment的是否执行了onDestroyView。

在onCreateView里我们注册各种view的callback事件,在onDestroyView中我们需要移除各种view的callback事件。

当一个fragment onAttach后activity都会执行onAttachFragment(), 在activity里我们可以持有当前fragment的引用。但只适合场景1,不适合场景2,3.

在onSaveInstanceState中存储临时数据,在onCreate,onActivityCreated, onCreateView。获取临时数据,什么时候获取根据数据在什么生命周期中被使用。

什么时候调用setRetainInstance?

setRetainInstance(true)时,当旋转屏幕时,fragment实例不会被销毁,重建时将不执行onDestroy()和onCreate。注意:只使用旋转屏幕的场景下,后fragment后台退出内存不足被销毁时,仍然会被完全重建。

所以当你的fragment使用AsyncTask下载等需要耗时长的任务时这种场景下,你需要setRetainInstance(true),因为我们是在onCreate创建AsyncTask对象的,这样可以避免AsyncTask被销毁重建。

当前fragment界面点击进入下一个fragment,上一个fragment不会执行onHiddenChanged()?

com.example.wenson.myfragmenttest I/Wen.Activity: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onStart

com.example.wenson.myfragmenttest I/Wen.Activity: onStart

com.example.wenson.myfragmenttest I/Wen.Activity: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onStart

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onResume

从log分析进入下一个fragment后上一个fragment仍然是onResume状态。

我们可以将启动下一个fragment的方式修改为如下:

Fragment fragmentTwo = FragmentTwo.newInstance("","");

getSupportFragmentManager()

.beginTransaction()

.addToBackStack(FragmentTwo.TAG)

.add( R.id.content, fragmentTwo, FragmentTwo.TAG)

.hide(mCurrentFragment)

.commit();

修改后在第二个fragment界面按返回键后会回退到第一个fragment界面,并且会响应onHiddenChanged()。

一个activity同时显示多个fragment

com.example.wenson.myfragmenttest I/Wen.Activity: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onStart

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onStart

com.example.wenson.myfragmenttest I/Wen.Activity: onStart

com.example.wenson.myfragmenttest I/Wen.Activity: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onResume

按返回键退出

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onPause

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onPause

com.example.wenson.myfragmenttest I/Wen.Activity: onPause

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onStop

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onStop

com.example.wenson.myfragmenttest I/Wen.Activity: onStop

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onDestroyView

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onDestroy

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onDetach

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onDestroyView

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onDestroy

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onDetach

com.example.wenson.myfragmenttest I/Wen.Activity: onDestroy

从log分析可知

● 如果有2个fragment,则 Activity: onAttachFragment 会被调用2次

● 2个fragment依次执行onAttach onCreate,

● 再依次执行 onCreateView onActivityCreated

Activity viewpager 2个fragment

com.example.wenson.myfragmenttest I/Wen.Activity: onCreate

com.example.wenson.myfragmenttest I/Wen.Activity: onStart

com.example.wenson.myfragmenttest I/Wen.Activity: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onAttach

com.example.wenson.myfragmenttest I/Wen.Activity: onAttachFragment

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onCreate

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onStart

com.example.wenson.myfragmenttest I/Wen.FragmentOne: onResume

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onCreateView

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onActivityCreated

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onStart

com.example.wenson.myfragmenttest I/Wen.FragmentTwo: onResume

从log分析:

Activity viewpager 持有多个2个fragment 时,Acvitity 与fragment的生命周期不相关了

总结:

在不同场景下activity和fragment的生命周期可能不同,所以我们需要理解之间的差异,在fragment正确的生命周期中处理好异步调用,数据存储等操作。

代码实例:

https://github.com/wensonli/MyFragmentTest

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值