一次搞懂Fragment的生命周期以及FragmentTransaction的提交方法

一、生命周期简介

Fragment的生命周期和Activity类似,但比Activity的生命周期复杂一些,首先我们来看张图


icon

onAttach():

当Fragment和Activity相关联时调用。可以通过该方法获取Activity引用,还可以通过getArguments()获取参数。

onCreate():

当Fragment被创建时调用。

onCreateView():

当Fragment的布局被创建时调用。

onActivityCreated():

当Activity完成onCreate()时调用。

onStart():

当Fragment可见时调用。

onResume():

当Fragment可见且可交互时调用。

onPause():

当Fragment不可交互但可见时调用。

onStop():

当Fragment不可见时调用。

onDestroyView():

当Fragment的从视图结构中移除时调用。

onDestroy():

当销毁Fragment时调用。

onDetach():

当Fragment和Activity解除关联时调用。

二、生命周期的调用

先看一段代码,介绍一下transaction.addToBackStack(null)这个方法,这个方法是将Fragment加入到回退栈。官方的说法是取决于你是否要在回退的时候显示上一个Fragment。

 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 transaction.replace(R.id.fragment_view, fragment);
 // transaction.addToBackStack(null);
 transaction.commitAllowingStateLoss();

1.Activity中调用replace()方法时的生命周期

新替换的Fragment:onAttach() > onCreate() > onCreateView() > onViewCreated() > onActivityCreated() > onStart() > onResume()

被替换的Fragment:onPause() > onStop() > onDestroyView() > onDestroy() > onDetach()

2.Activity中调用replace()方法和addToBackStack()方法时的生命周期

新替换的Fragment(没有在BackStack回退栈中):onAttach() > onCreate() > onCreateView() > onViewCreated() > onActivityCreated() > onStart() > onResume()

新替换的Fragment(已经在BackStack回退栈中):onCreateView() > onViewCreated() > onActivityCreated() > onStart() > onResume()

被替换的Fragment:onPause() > onStop() > onDestroyView()

三、FragmentTransaction的提交方法

FragmentTransaction现在提供了四种不同的方法来commit一个transaction:commit()、commitAllowingStateLoss()、commitNow()、commitNowAllowingStateLoss()。

1.commit()

当你调用commit()的时候, FragmentManger会检查是否已经存储了它自己的状态, 如果已经存了, 就抛出IllegalStateException。一旦调用这个方法, 这个commit()并不是立即执行的, 它会被发送到主线程的任务队列当中去, 当主线程准备好执行它的时候执行

2.commitAllowingStateLoss()

当你调用commitAllowingStateLoss()的时候, FragmentManger不会检查是否已经存储了它自己的状态, 也就不会抛出IllegalStateException.有效的解决了commit()提交时出现的问题。

问题::如果你调用的是commitAllowingStateLoss(), 并且是在onSaveInstanceState()之后, 你可能会丢失掉什么状态呢?

答案:你可能会丢掉FragmentManager的状态, 即save之后任何被添加或被移除的Fragments。有同学会疑问,都已经提交了,怎么还会丢失save之后任何被添加或被移除的Fragments呢?因为这个方法是异步的,并不是立即执行。

3.commitNow()

当你调用commitNow()时,将会立即执行并且只会执行你当前要提交的transaction。
从v24.0.0开始提供了 commitNow()方法,在之前开发者会在commit()调用之后加上 executePendingTransactions()来保证立即执行, 即变异步为同步,但是这样会将所有pending在队列中还有你新提交的transactions都执行了,而commitNow()就避免那些你可能并不想执行的transactions。

问题:addToBackStack()和commitNow()是否可以同时使用?

答案:不可以。想想一下, addToBackStack()是把被替换的Fragment放入回退栈中,如果你有一个提交使用了commit(), 紧接着又有另一个提交使用了commitNow(), 两个都想加入back stack, 那back stack会变成什么样呢? 到底是哪个transaction在上, 哪个在下? 答案将是一种不确定的状态, 因为系统并没有提供任何保证来确保顺序, 所以系统决定干脆不支持这个操作。

4.commitNowAllowingStateLoss()

当你调用commitNowAllowingStateLoss()的时候, FragmentManger不会检查是否已经存储了它自己的状态, 也就不会抛出IllegalStateException,并且会立即执行。

在实际开发中怎么去选择使用哪种提交方法呢?

1.如果你操作很多transactions, 并且不需要同步, 或者你需要把transactions加在back stack里, 那就使用commit().
2.如果你需要同步的操作, 并且你不需要加到back stack里, 使用commitNow().
3.当报错“IllegalStateException:Can not perform this action after onSaveInstanceState”时,使用commitAllowingStateLoss()。
4.如果你希望在某一个指定的点, 确保所有的transactions都被执行, 那么使用executePendingTransactions().

END~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容