理解片段事务期间片段的生命周期方法调用

Posted

技术标签:

【中文标题】理解片段事务期间片段的生命周期方法调用【英文标题】:Understanding Fragment's lifeCycle methods calls during fragment transaction 【发布时间】:2017-07-02 07:03:12 【问题描述】:

我创建了一个演示来了解在片段事务的不同情况下调用了所有片段生命周期的方法。虽然大多数调用都符合预期,但我仍然感到困惑的是我用粗体写的。

假设有两个片段 A 和 B,我们正在它们之间执行事务

案例一

当 Fragment B 添加到 Fragment A 时

getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, fragementB).addToBackStack(null).commit();

片段 B

附加

onCreate

onCreateView

onActivityCreated

开始

onResume

没有调用 Fragment A 的生命周期方法。

我的预期是什么?

由于 Fragment A 不可见,调用了 Fragment A 的 onStop 方法

根据文档-

已停止 - 片段不可见。要么主机活动已经 已停止或片段已从活动中删除但已添加 到后栈。停止的片段仍然存在(所有状态和 会员信息由系统保留)。然而,它不是 对用户可见的时间更长,如果活动被终止,将被杀死 被杀了。

这是否意味着在同一个activity中添加新的fragment时不会调用当前fragment的方法?

然后在片段 B 中使用popBackStack()

片段 B

暂停

在停止

onDestroyView

onDestroy

onDetach

没有调用 Fragment A 的生命周期方法

我的预期是什么?

Fragment A 的 onStart 方法被调用,因为 Fragment A 现在可见

案例 2

当片段 B 替换片段 A

getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragementB).commit();

片段 B

附加

onCreate

onCreateView

onActivityCreated

开始

onResume

片段 A

暂停

在停止

onDestroyView

onDestroy

onDetach

一切都如你所愿

案例 3

当 Fragment B 替换 Fragment A 时将其保留在 backstack 中

 getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragementB).addToBackStack("tag").commit();

片段 B

附加

onCreate

onCreateView

onActivityCreated

开始

onResume

片段 A

暂停

在停止

onDestroyView

没有调用 Fragment A 的 onDestroy 和 onDetach 方法。为什么没有调用它?Bcoz 根据文档方法replace 删除容器中已经存在的所有片段并将新片段添加到同一个容器中强>

然后在片段 B 中使用popBackStack()

片段 A

onCreateView

onActivityCreated

开始

onResume

片段 B

暂停

在停止

onDestroyView

onDestroy

onDetach

【问题讨论】:

感谢 Hanan Rofe Haim..我已经在博客上详细发布了解释..它解释了片段交易期间的片段生命周期与最新的 appcompat 版本..查看 - androidlearnersite.wordpress.com/2017/02/27/… 【参考方案1】:

这是否意味着在同一活动中添加新片段时不会调用当前片段的方法?

正确,您的第一个片段 A 只有在被移除或替换时才会受到影响(情况 2)。 简单地添加另一个片段只会在片段 A 上显示片段 B,并且不应调用生命周期回调。

我的预期是什么?

Fragment A 的 onStart 方法被调用,因为 Fragment A 现在可见

同样,由于片段 B 是在 A 之上添加的,因此片段 A 不受 B 移除的影响。

没有调用 Fragment A 的 onDestroy 和 onDetach 方法。为什么没有调用它?Bcoz 根据文档方法替换删除容器中已经存在的所有片段并将新片段添加到同一个容器中

与简单的替换不同,当您将替换事务添加到后台堆栈时,您实际上是在将第一个片段附加到它的活动中,只有它的视图被销毁。

一旦你弹出 backstack 片段 B 被删除,片段 A 将重新创建它的视图 - 从 onCreateView() 开始。

【讨论】:

简单明了的答案。【参考方案2】:

我运行一些日志查看结果如下(就像这里的活动中所做的那样:https://***.com/a/61299029/3904109

片段开始

On Fragment Launched (First Time)
———————————————————————
onAttach: 
onCreateView:
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


On Coming Back To Fragment (From another fragment)
———————————————————————
onCreateView: 
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


OnMaximize(Square Button-After Back Pressed)
———————————————————————
onAttach: 
onCreateView: 
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


OnMaximize(Square Button-After Circle Button)
———————————————————————
onStart: 
onResume:


OnMaximize(After Circle Button)
————————————————————————————————————————————————
onStart: 
onResume:

片段停止

On Going To Another Fragment (Skipping 1 Fragment)
———————————————————————
onPause: 
onStop: 
onDestroyView: 


On BackPressed - Reverse Triangle Button (App Minimized)
———————————————————————
onPause: 
onStop: 
onDestroyView: 
onDestroy: 
onDetach: 


OnMinimize (Circle Button)
————————————————————————————————————————————————
onPause: 
onStop: 


OnMinimize (Square Button)
————————————————————————————————————————————————
onPause: 
onStop: 


Going To Another Activity
————————————————————————————————————————————————
onPause: 
onStop: 


Close The App
————————————————————————————————————————————————
onDestroyView: 
onDestroy:

如果有人想重新创建检查以下是代码:

public View onCreateView(@NonNull LayoutInflater inflater,
                         @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) 

    Log.d("TAG",
          "onCreateView: ");


@Override
public void onAttach(Context context) 
    Log.d("TAG",
          "onAttach: ");
    super.onAttach(context);


@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) 

    Log.d("TAG",
          "onViewCreated: ");
    super.onViewCreated(view,
                        savedInstanceState);


@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) 
    Log.d("TAG",
          "onActivityCreated: ");
    super.onActivityCreated(savedInstanceState);


@Override
public void onStart() 
    Log.d("TAG",
          "onStart: ");
    super.onStart();


@Override
public void onResume() 

    Log.d("TAG",
          "onResume: ");

    reAttachListeners();
    super.onResume();


@Override
public void onPause() 
    super.onPause();

    Log.d("TAG",
          "onPause: ");
    removeListeners();



@Override
public void onStop() 
    Log.d("TAG",
          "onStop: ");
    super.onStop();


@Override
public void onDestroyView() 
    Log.d("TAG",
          "onDestroyView: ");
    super.onDestroyView();


@Override
public void onDestroy() 
    Log.d("TAG",
          "onDestroy: ");
    super.onDestroy();


@Override
public void onDetach() 

    Log.d("TAG",
          "onDetach: ");
    super.onDetach();

【讨论】:

就像在活动中 onPause 和 onResume 似乎一直被调用,除了关闭应用程序......所以这有助于 firebase 听众,我很惊讶有这么多教程没有涵盖附加和分离 addvalueeventlisteners 的这个关键方面......【参考方案3】:

setUserVisibleHint 将在片段可见或不可见时调用

【讨论】:

它基本上是一个设置器,它向系统设置关于该片段的 UI 当前是否对用户可见的提示。它不是一个生命周期方法,当添加或替换新片段时将调用它当前片段

以上是关于理解片段事务期间片段的生命周期方法调用的主要内容,如果未能解决你的问题,请参考以下文章

导航架构片段重载问题

自动挂钩到 Activity 生命周期方法的异步任务库

关于片段生命周期,何时调用片段的 onActivityResult?

Android 片段生命周期

调用 replace() 时片段的生命周期是啥?

关于其活动的片段生命周期