基于Android Api 33
Activity的生命周期与Fragment生命周期的关联
示例代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/f1"
android:text="Fragment 1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<fragment android:name="com.example.test_android.Fragment1"
android:id="@+id/prefill_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/f1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/content_fragment"
/>
<FrameLayout
android:id="@+id/content_fragment"
android:background="#8EFDCB"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/prefill_fragment"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
class MainActivity : FragmentActivity() {
var f1: Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
Log.d("swithun-xxxx", "MainActivity onCreate")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
f1 = findViewById(R.id.f1)
f1()
Log.d("swithun-xxxx", "MainActivity onCreate end")
}
override fun onStart() {
Log.d("swithun-xxxx", "MainActivity onStart begin")
super.onStart()
Log.d("swithun-xxxx", "MainActivity onStart end")
}
override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
Log.d("swithun-xxxx", "MainActivity onCreateView 1")
return super.onCreateView(name, context, attrs)
}
override fun onCreateView(
parent: View?,
name: String,
context: Context,
attrs: AttributeSet
): View? {
Log.d("swithun-xxxx", "MainActivity onCreateView 2")
return super.onCreateView(parent, name, context, attrs)
}
override fun onAttachFragment(fragment: Fragment) {
Log.d("swithun-xxxx", "MainActivity onAttachFragment")
super.onAttachFragment(fragment)
}
override fun onResume() {
Log.d("swithun-xxxx", "MainActivity onResume")
super.onResume()
}
override fun onStop() {
Log.d("swithun-xxxx", "MainActivity onResume")
super.onStop()
}
override fun onDestroy() {
Log.d("swithun-xxxx", "MainActivity onDestroy")
super.onDestroy()
}
private fun f1() {
f1?.setOnClickListener {
val transaction = supportFragmentManager.beginTransaction();
transaction.add(R.id.content_fragment, Fragment2())
transaction.commit()
}
}
}
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.fragment.app.Fragment
open class Fragment1: Fragment() {
open val name = "fragment 1"
override fun onAttach(context: Context) {
Log.d("swithun-xxxx", "$name onAttach")
super.onAttach(context)
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.d("swithun-xxxx", "$name onCreate")
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// 居中添加一个TextView——“hello Fragment1"
Log.d("swithun-xxxx", "$name onCreateView")
val view = TextView(context)
val param = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
param.gravity = Gravity.CENTER
view.layoutParams = param
view.text = "hello $name"
view.textSize = 15F
view.gravity = Gravity.CENTER
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Log.d("swithun-xxxx", "$name onViewCreated")
super.onViewCreated(view, savedInstanceState)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
Log.d("swithun-xxxx", "$name onActivityCreated")
super.onActivityCreated(savedInstanceState)
}
override fun onStart() {
Log.d("swithun-xxxx", "$name onStart")
super.onStart()
}
override fun onResume() {
Log.d("swithun-xxxx", "$name onResume")
super.onResume()
}
override fun onPause() {
Log.d("swithun-xxxx", "$name onPause")
super.onPause()
}
override fun onStop() {
Log.d("swithun-xxxx", "$name onStop")
super.onStop()
}
override fun onDestroyView() {
Log.d("swithun-xxxx", "$name onDestroyView")
super.onDestroyView()
}
override fun onDestroy() {
Log.d("swithun-xxxx", "$name onDestroy")
super.onDestroy()
}
override fun onDetach() {
Log.d("swithun-xxxx", "$name onDetach")
super.onDetach()
}
}
class Fragment2: Fragment1() {
override val name: String = "Fragment 2"
}
通过xml文件添加Fragment —— Fragment1
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
<fragment android:name="com.example.test_android.Fragment1"
android:id="@+id/prefill_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/f1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/content_fragment"
/>
...
</androidx.constraintlayout.widget.ConstraintLayout>
先从代码分析,从FragmentActivity
.onCreate
开始看
[T-1] MainActivity.onCreate
// MainActivity class MainActivity : FragmentActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { [:0] super.onCreate(savedInstanceState) [:1] setContentView(R.layout.activity_main)
关键节点 [:0] FragmentActivity.onCreate
-
[:0] FragmentActivity.onCreate
// androidx.fragment.app.FragmentActivity protected void onCreate(@Nullable Bundle savedInstanceState) { ... [:0:1] mFragments.dispatchCreate(); }
sequenceDiagram autonumber participant FragmentActivity participant FragmentController FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController FragmentActivity --> FragmentController: hold
可以看出
FragmentActivity
持有FragmentController
- 通知
FragmentController
分发create
事件
-
[:0:1] mFragments.dispatchCreate()
// androidx.fragment.app.FragmentController public void dispatchCreate() { [:0:1:0] mHost.mFragmentManager.dispatchCreate(); }
sequenceDiagram autonumber participant FragmentActivity participant FragmentController FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentController->>FragmentManager: dispatchCreate
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController { - FragmentHostCallback<?> mHost } class FragmentManager { <<abstract>> } class FragmentManagerImpl class FragmentHostCallback { <<abstract>> - FragmentManager mFragmentManager } FragmentActivity --> FragmentController: hold FragmentController --> FragmentHostCallback: hold FragmentHostCallback --> FragmentManager: hold FragmentManagerImpl --|> FragmentManager: implements
可以看出
FragmentController
持有FragmentHostCallback
持有FragmentManger
- 通知
FragmentManager
分发create
事件
-
[:0:1:0] mHost.mFragmentManager.dispatchCreate()
// androidx.fragment.app.FragmentManager void dispatchCreate() { ... [:0:1:0:0] dispatchStateChange(Fragment.CREATED); ... }
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner, ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner, ActivityResultCaller { static final int INITIALIZING = -1; // Not yet attached. static final int ATTACHED = 0; // Attached to the host. static final int CREATED = 1; // Created. static final int VIEW_CREATED = 2; // View Created. static final int AWAITING_EXIT_EFFECTS = 3; // Downward state, awaiting exit effects static final int ACTIVITY_CREATED = 4; // Fully created, not started. static final int STARTED = 5; // Created and started, not resumed. static final int AWAITING_ENTER_EFFECTS = 6; // Upward state, awaiting enter effects static final int RESUMED = 7; // Created started and resumed.
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant FragmentManager FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentController->>FragmentManager: dispatchCreate FragmentManager->>FragmentManager: dispatchStateChange
可以看出
FragmentManager
内部分发Fragment.CREATED
事件——Attached to the host
-
[:0:1:0:0] dispatchStateChange(Fragment.CREATED)
// androidx.fragment.app.FragmentManager private void dispatchStateChange(int nextState) { ... [:0:1:0:0:0] mFragmentStore.dispatchStateChange(nextState); [:0:1:0:0:1] moveToState(nextState, false); ... }
public abstract class FragmentManager implements FragmentResultOwner { ... private final FragmentStore mFragmentStore = new FragmentStore();
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant FragmentManager participant FragmentStore FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentController->>FragmentManager: dispatchCreate FragmentManager->>FragmentManager: dispatchStateChange FragmentManager->>FragmentStore: dispatchStateChange
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController { - FragmentHostCallback<?> mHost } class FragmentManager { <<abstract>> FragmentStore mFragmentStore } class FragmentManagerImpl class FragmentHostCallback { <<abstract>> - FragmentManager mFragmentManager } class FragmentStore FragmentActivity --> FragmentController: hold FragmentController --> FragmentHostCallback: hold FragmentHostCallback --> FragmentManager: hold FragmentManagerImpl --|> FragmentManager: implements FragmentManager --> FragmentStore: hold
可以看出
FragmentManager
持有一个FragmentStore
FragmentStore
分发收到的状态nextState
——Fragment.CREATED
-
[:0:1:0:0:0] mFragmentStore.dispatchStateChange(nextState)
// androidx.fragment.app.FragmentStore void dispatchStateChange(int state) { for (FragmentStateManager fragmentStateManager : mActive.values()) { if (fragmentStateManager != null) { [:0:1:0:0:0:0] fragmentStateManager.setFragmentManagerState(state); } } }
mActive
是存储FragmentStateManager
的Map
:⬇️// androidx.fragment.app.FragmentStore class FragmentStore { ... private final HashMap<String, FragmentStateManager> mActive = new HashMap<>();
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant FragmentManager participant FragmentStore participant FragmentStateManager FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentController->>FragmentManager: dispatchCreate FragmentManager->>FragmentManager: dispatchStateChange FragmentManager->>FragmentStore: dispatchStateChange FragmentStore->>FragmentStateManager: setFragmentManagerState
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController { - FragmentHostCallback<?> mHost } class FragmentManager { <<abstract>> FragmentStore mFragmentStore } class FragmentManagerImpl class FragmentHostCallback { <<abstract>> - FragmentManager mFragmentManager } class FragmentStore { HashMap「String, FragmentStateManager」 mActive } class FragmentStateManager FragmentActivity --> FragmentController: hold FragmentController --> FragmentHostCallback: hold FragmentHostCallback --> FragmentManager: hold FragmentManagerImpl --|> FragmentManager: implements FragmentManager --> FragmentStore: hold FragmentStore "1" --> "n" FragmentStateManager: hold
可以看出
FragmentStore
持有n个FragmentStateManager
FragmentManager
将收到的状态分发给每一个FragmentStateManager
[总结]: 由于
FragmentActivity
此时尚未setContentView
,所以FragmentManger
管理的Fragment
数量实际上为0,mActive
自然为0。但是我们仍然继续看下如果不为0会继续做什么。 -
[:0:1:0:0:0:0] fragmentStateManager.setFragmentManagerState(state)
// androidx.fragment.app.FragmentStateManager void setFragmentManagerState(int state) { mFragmentManagerState = state; }
// androidx.fragment.app.FragmentStateManager class FragmentStateManager { ... private final Fragment mFragment; private int mFragmentManagerState = Fragment.INITIALIZING;
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController { - FragmentHostCallback<?> mHost } class FragmentManager { <<abstract>> FragmentStore mFragmentStore } class FragmentManagerImpl class FragmentHostCallback { <<abstract>> - FragmentManager mFragmentManager } class FragmentStore { HashMap「String, FragmentStateManager」 mActive } class FragmentStateManager { Fragment mFragment int mFragmentManagerState } class Fragment FragmentActivity --> FragmentController: hold FragmentController --> FragmentHostCallback: hold FragmentHostCallback --> FragmentManager: hold FragmentManagerImpl --|> FragmentManager: implements FragmentManager --> FragmentStore: hold FragmentStore "1" --> "n" FragmentStateManager: hold FragmentStateManager --> Fragment: hold
可以看出
FragmentStateManager
1:1 持有Fragment
FragmentStateManaget
持有变量mFragmentManagerState
——所属的FragmentManager的状态
至此,
FragmentActivity
将CREATE
状态通知到FragmentManager
进而通知到管理的每个FragmentStateManager
——但是此时Fragment尚未更新。[总结]: (只关心重要的
FragmentActivity
,FragmentManager
,Fragment
)sequenceDiagram autonumber participant FragmentActivity participant FragmentManager participant Fragment FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentManager: dispatchCreate() 分发CREATE
-
[:0:1:0:0:1] moveToState(nextState, false);
// androidx.fragment.app.FragmentManager void moveToState(int newState, boolean always) { ... mFragmentStore.moveToExpectedState(); ...
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant FragmentManager participant FragmentStore FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentController->>FragmentManager: dispatchCreate FragmentManager->>FragmentManager: dispatchStateChange FragmentManager->>FragmentStore: dispatchStateChange FragmentManager->>FragmentManager: moveToState
[:0:1:0:0:0:0]
只是将用来管理Fragment
的FragmentStateManager
的状态更新了,这里才是真正更新Fragment
的状态——但是此时FragmentManager
管理的Fragment
数量实际上为0,所以这里先不继续看,后续流程下面[:1:0:0:1]
会继续讲到。
关键节点 [:1] setContentView(R.layout.activity_main)
-
[:1] setContentView(R.layout.activity_main)
执行[:0] super.onCreate(savedInstanceState)
之后,setContentView// androidx.activity.ComponentActivity @Override public void setContentView(@LayoutRes int layoutResID) { ... [:1:0] super.setContentView(layoutResID); }
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController class Activity FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity
-
[:1:0] super.setContentView(layoutResID);
ComponentActivity
调用父类Activity
.setContentView
// android.app.Activity public void setContentView(@LayoutRes int layoutResID) { [:1:0:0] getWindow().setContentView(layoutResID); ...
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant Window FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>Window: setContentView
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController class Activity { - Window mWindow } FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity Activity --> Window: hold
-
[:1:0:0] getWindow().setContentView(layoutResID);
Window
.setContentView
// android.view.Window public abstract void setContentView(@LayoutRes int layoutResID);
继续-跳过细节 根据传入的layout ResId 初始化 view
// com.android.internal.policy.PhoneWindow @Override public void setContentView(int layoutResID) { ... [...] mLayoutInflater.inflate(layoutResID, mContentParent); ...
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController class Activity { - Window mWindow } class PhoneWindow { - LayoutInflater mLayoutInflater } class LayoutInflater FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity Activity --> Window: hold PhoneWindow --|> Window PhoneWindow --> LayoutInflater: hold
mContentParent
为PhoneWindow
的根View,下面会根据layoutResID
构造View
并add到mContentParent
继续-跳过细节 根据传入的layout ResId 初始化 view// android.view.LayoutInflater public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null);
// android.view.LayoutInflater public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) { [...] return inflate(parser, root, attachToRoot); ... }
attachToRoot
为true(root != null
)// android.view.LayoutInflater public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) { synchronized (mConstructorArgs) { ... advanceToRootNode(parser); // 让parser移动到下一个要解析的"结点" final String name = parser.getName(); // 获取结点名字 ... // 根据名字构造xml的根view final View temp = createViewFromTag(root, name, inflaterContext, attrs); ... // 继续递归构造xml根view的子view,并addView到根view rInflateChildren(parser, temp, attrs, true);
根据
xml parser
构造View
,temp
是xml
的根标签代表的view,根据activity_main.xml
xml-1
⬇️<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout ...> <Button..> <fragment android:name="com.example.test_android.Fragment1"...> <FrameLayout android:id="@+id/content_fragment"...> </androidx.constraintlayout.widget.ConstraintLayout>
name
则为根标签androidx.constraintlayout.widget.ConstraintLayout
,
temp
相应的则是androidx.constraintlayout.widget.ConstraintLayout
,
下面rInflateChildren
则是继续递归的构造ConstraintLayout
中的子view。(开头的r
代表的是Recursive--递归)// android.view.LayoutInflater final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException { rInflate(parser, parent, parent.getContext(), attrs, finishInflate);
// android.view.LayoutInflater void rInflate(XmlPullParser parser, View parent, Context context, AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException { ... while (((type = parser.next()) != XmlPullParser.END_TAG || ... final View view = createViewFromTag(parent, name, context, attrs); ...
rInflate
: 继续递归构造temp
的子viewparser.next
: 不断的获取下一个要解析的标签,根据xml-1
,会解析到<fragment
标签——通过createViewFromTag
构造Fragment// android.view.LayoutInflater private View createViewFromTag(View parent, String name, Context context, AttributeSet attrs) { return createViewFromTag(parent, name, context, attrs, false);
// android.view.LayoutInflater View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, ... View view = tryCreateView(parent, name, context, attrs); ...
构造fragment view
// android.view.LayoutInflater public final View tryCreateView(@Nullable View parent, @NonNull String name, ... view = mPrivateFactory.onCreateView(parent, name, context, attrs); ...
// android.view.LayoutInflater private Factory2 mPrivateFactory;
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater participant LayoutInflater-Factory2 FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate LayoutInflater->>LayoutInflater-Factory2: onCreateView
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController class Activity { - Window mWindow } class PhoneWindow { - LayoutInflater mLayoutInflater } class LayoutInflater class `LayoutInflater-Factory2` FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity Activity --> Window: hold PhoneWindow --|> Window PhoneWindow --> LayoutInflater: hold Activity --|> `LayoutInflater-Factory2` LayoutInflater --> `LayoutInflater-Factory2`: hold
mPrivateFactory
实际上是我们写的的MainActivity
,所以继续会走到MainActivity.onCreateView
// androidx.fragment.app.FragmentActivity public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs); if (v == null) { return super.onCreateView(parent, name, context, attrs); } return v; }
@param View parent
: xml的根布局ConstraintLayout
@param String name
:fragment
,也就是xml-1
中的fragment
标签dispatchFragmentsOnCreateView(
: 会先尝试通过该方法处理fragment
标签对应的View,如果有返回结果则跳过if (v == null)
中的逻辑,我们这里name
为framgment
,所以不应该返回null。sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater participant LayoutInflater-Factory2 FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate LayoutInflater->>LayoutInflater-Factory2: onCreateView LayoutInflater-Factory2->>FragmentActivity: onCreateView
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController class Activity { - Window mWindow } class PhoneWindow { - LayoutInflater mLayoutInflater } class LayoutInflater class `LayoutInflater-Factory2` FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity Activity --> Window: hold PhoneWindow --|> Window PhoneWindow --> LayoutInflater: hold Activity --|> `LayoutInflater-Factory2` LayoutInflater --> `LayoutInflater-Factory2`: hold
// androidx.fragment.app.FragmentActivity @Nullable final View dispatchFragmentsOnCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { return mFragments.onCreateView(parent, name, context, attrs);
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater participant LayoutInflater-Factory2 FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate LayoutInflater->>LayoutInflater-Factory2: onCreateView LayoutInflater-Factory2->>FragmentActivity: onCreateView FragmentActivity->>FragmentController: onCreateView
// androidx.fragment.app.FragmentController public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { return mHost.mFragmentManager.getLayoutInflaterFactory() .onCreateView(parent, name, context, attrs); }
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater participant LayoutInflater-Factory2 participant FragmentLayoutInflaterFactory FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate LayoutInflater->>LayoutInflater-Factory2: onCreateView LayoutInflater-Factory2->>FragmentActivity: onCreateView FragmentActivity->>FragmentController: onCreateView FragmentController->>FragmentLayoutInflaterFactory: onCreateView
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController { FragmentHostCallback<?> mHost } class Activity { - Window mWindow } class PhoneWindow { - LayoutInflater mLayoutInflater } class LayoutInflater class `LayoutInflater-Factory2` class FragmentManager { FragmentLayoutInflaterFactory mLayoutInflaterFactory } class FragmentHostCallback { <<abstract>> FragmentManager mFragmentManager } class FragmentLayoutInflaterFactory FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity Activity --> Window: hold PhoneWindow --|> Window PhoneWindow --> LayoutInflater: hold Activity --|> `LayoutInflater-Factory2` LayoutInflater --> `LayoutInflater-Factory2`: hold FragmentController --> FragmentHostCallback: hold FragmentHostCallback --> FragmentManager: hold FragmentManager --> FragmentLayoutInflaterFactory: hold
return
FragmentActivity.dispatchFragmentsOnCreateView
returnFragmentController.onCreateView
returnFragmentLayoutInflaterFactory.onCreateView
// androidx.fragment.app.FragmentLayoutInflaterFactory public View onCreateView(@Nullable final View parent, @NonNull String name, ... // new Fragment fragment = mFragmentManager.getFragmentFactory().instantiate( context.getClassLoader(), fname); // fragment 的属性设置 begin fragment.mFromLayout = true; fragment.mFragmentId = id != 0 ? id : containerId; fragment.mContainerId = containerId; fragment.mTag = tag; fragment.mInLayout = true; fragment.mFragmentManager = mFragmentManager; fragment.mHost = mFragmentManager.getHost(); fragment.onInflate(mFragmentManager.getHost().getContext(), attrs, fragment.mSavedFragmentState); // fragment 的属性设置 end // 添加到mFragmentManager中,同时返回 持有Fragment的FragmentStateManager fragmentStateManager = mFragmentManager.addFragment(fragment); // 此时Fragment这个壳已经初始化,但是Fragment.mView实际上还没有构造 ... // 通过FragmentStateManager更新他持有的一对一的Fragment的State [:1:0:0:1] fragmentStateManager.moveToExpectedState(); // 确保走到这行代码是Fragment已经构造好view [B2] fragmentStateManager.ensureInflatedView();
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater participant LayoutInflater-Factory2 participant FragmentLayoutInflaterFactory participant Fragment participant FragmentStateManager FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate LayoutInflater->>LayoutInflater-Factory2: onCreateView LayoutInflater-Factory2->>FragmentActivity: onCreateView FragmentActivity->>FragmentController: onCreateView FragmentController->>FragmentLayoutInflaterFactory: onCreateView FragmentLayoutInflaterFactory->>Fragment: new FragmentLayoutInflaterFactory->>FragmentManager: addFragment FragmentManager->>FragmentLayoutInflaterFactory: addFragment return FragmentStateManager FragmentLayoutInflaterFactory->>FragmentStateManager: moveToExpectedState
classDiagram class FragmentActivity { - FragmentController mFragments } class FragmentController { FragmentHostCallback<?> mHost } class Activity { - Window mWindow } class PhoneWindow { - LayoutInflater mLayoutInflater } class LayoutInflater class `LayoutInflater-Factory2` class FragmentManager { FragmentLayoutInflaterFactory mLayoutInflaterFactory } class FragmentHostCallback { <<abstract>> FragmentManager mFragmentManager } class FragmentLayoutInflaterFactory { FragmentManager mFragmentManager } FragmentActivity --> FragmentController: hold FragmentActivity --|> Activity Activity --> Window: hold PhoneWindow --|> Window PhoneWindow --> LayoutInflater: hold Activity --|> `LayoutInflater-Factory2` LayoutInflater --> `LayoutInflater-Factory2`: hold FragmentController --> FragmentHostCallback: hold FragmentHostCallback --> FragmentManager: hold FragmentManager --> FragmentLayoutInflaterFactory: hold FragmentLayoutInflaterFactory --> FragmentManager: ref
fragmentStateManager = mFragmentManager.addFragment(fragment);
: 将新建的Fragment
添加到FragmentManager
中进行管理。
-
[:1:0:0:1] fragmentStateManager.moveToExpectedState();
通过FragmentStateManager更新他持有的一对一的Fragment的State// androidx.fragment.app.FragmentStateManager void moveToExpectedState() { ... int newState; [:1:0:0:1:0] while ((newState = computeExpectedState()) != mFragment.mState) { if (newState > mFragment.mState) { // Moving upward int nextStep = mFragment.mState + 1; switch (nextStep) { case Fragment.ATTACHED: [:1:0:0:1:1] attach(); case Fragment.CREATED: [:1:0:0:1:2] create(); break; case Fragment.VIEW_CREATED: [:1:0:0:1:3] ensureInflatedView(); [:1:0:0:1:4] createView(); break;
-
[:1:0:0:1:0] while ((newState = computeExpectedState()) != mFragment.mState) {
computeExpectedState()
: 根据FragmentManager等等计算mFragment应该达到的状态,先不看这里的复杂计算,但是最终的结果是2,对应Fragment.VIEW_CREATED
,即Fragment应该进行到构造好View的状态while
:mFragment
不断切换到下一个状态,直到达到目标状态——VIEW_CREATED
mFragment.mState
: 当前mFragment.mState
为INITIALIZING
,则表示会依次执行FragmentManager.attach()
、FragmentManager.create()
、FragmentManager.createView()
static final int INITIALIZING = -1; // Not yet attached. static final int ATTACHED = 0; // Attached to the host. static final int CREATED = 1; // Created. static final int VIEW_CREATED = 2; // View Created. static final int AWAITING_EXIT_EFFECTS = 3; // Downward state, awaiting exit effects static final int ACTIVITY_CREATED = 4; // Fully created, not started. static final int STARTED = 5; // Created and started, not resumed. static final int AWAITING_ENTER_EFFECTS = 6; // Upward state, awaiting enter effects static final int RESUMED = 7; // Created started and resumed.
-
[:1:0:0:1:1] attach();
// androidx.fragment.app.FragmentStateManager void attach() { .... [:1:0:0:1:1:0] mFragment.performAttach(); mDispatcher.dispatchOnFragmentAttached(mFragment, false); }
sequenceDiagram autonumber participant FragmentActivity participant FragmentController participant Activity participant PhoneWindow participant LayoutInflater participant LayoutInflater-Factory2 participant FragmentLayoutInflaterFactory participant Fragment participant FragmentStateManager FragmentActivity->>FragmentActivity: onCreate begin FragmentActivity->>FragmentController: dispatchCreate FragmentActivity->>Activity: setContentView Activity->>PhoneWindow: setContentView PhoneWindow->>LayoutInflater: inflate LayoutInflater->>LayoutInflater-Factory2: onCreateView LayoutInflater-Factory2->>FragmentActivity: onCreateView FragmentActivity->>FragmentController: onCreateView FragmentController->>FragmentLayoutInflaterFactory: onCreateView FragmentLayoutInflaterFactory->>Fragment: new FragmentLayoutInflaterFactory->>FragmentManager: addFragment FragmentManager->>FragmentLayoutInflaterFactory: addFragment return FragmentStateManager FragmentLayoutInflaterFactory->>FragmentStateManager: moveToExpectedState FragmentStateManager->>Fragment: performAttach
-
[:1:0:0:1:1:0] mFragment.performAttach()
// androidx.fragment.app.Fragment void performAttach() { ... mState = ATTACHED; onAttach(mHost.getContext()); ... mChildFragmentManager.dispatchAttach(); }
mState = ATTACHED
: 更新Fragment
状态为ATTACHED
// androidx.fragment.app.Fragment public void onAttach(@NonNull Context context) { mCalled = true; final Activity hostActivity = mHost == null ? null : mHost.getActivity(); if (hostActivity != null) { mCalled = false; onAttach(hostActivity); } }
// androidx.fragment.app.Fragment public void onAttach(@NonNull Activity activity) { mCalled = true; }
至此,Fragment
的状态由INITIALIZING
切换到ATTACHED
切换到CREATED
切换到VIEW_CREATED
,关键方法是B1
-fragmentStateManager.moveToExpectedState
,不断的将FragmentStateManager
所管理的所有Fragment
推动到应该达到的状态。
sequenceDiagram
autonumber
participant FragmentActivity
participant FragmentManager
participant Fragment
activate FragmentActivity
FragmentActivity->>FragmentActivity: onCreate begin
FragmentActivity->>FragmentManager: dispatchCreate() 分发CREATE
FragmentActivity->>FragmentActivity: setContentView begin
FragmentActivity->>FragmentActivity: onCreateView
FragmentActivity->>FragmentManager: moveToExpectedState
FragmentManager->>Fragment: performAttach
Fragment->>Fragment: onAttach
FragmentManager->>Fragment: performCreate
FragmentManager->>Fragment: performCreateView
FragmentActivity->>FragmentActivity: onCreate end
deactivate FragmentActivity
FragmentActivity->>FragmentActivity: onStart
以上以Create
为例,了解了FragmentActivity
的状态对Fragment
的状态影响以及FragmentActivity
, FragmentController
, FragmentManager
, FragmentStateManager
, Fragment
中间的关系。
MainActivity onCreate
MainActivity onCreateView 2
MainActivity onCreateView 1
MainActivity onCreateView 2
MainActivity onCreateView 1
MainActivity onCreateView 2
MainActivity onCreateView 1
MainActivity onCreateView 2
MainActivity onCreateView 1
MainActivity onCreateView 2
MainActivity onCreateView 1
MainActivity onCreateView 2
fragment 1 onAttach
MainActivity onAttachFragment
fragment 1 onCreate
fragment 1 onCreateView
fragment 1 onViewCreated
MainActivity onCreateView 2
MainActivity onCreateView 1
MainActivity onCreate end
MainActivity onStart begin
fragment 1 onActivityCreated
fragment 1 onStart
MainActivity onStart end
MainActivity onResume
fragment 1 onResumek
简单总结:
Activity 生命周期回调 | Fragment 生命周期回调 |
---|---|
onCreate | - onAttach - onCreate - onCreateView - onViewCreated |
onStart | - onActivityCreated - onStart |
onResume | - onResume |
总结
总结以上,FragmentActivity
onCreate
时将 Create
事件 FragmentController
FragmentManager
持有的每个 FragmentStateManager
Fragment
。
代码中动态添加Fragment
// MainActivity
private fun f1() {
f1?.setOnClickListener {
[:2] val transaction = supportFragmentManager.beginTransaction()
[:3] transaction.add(R.id.content_fragment, Fragment2())
[:4] transaction.commit()
}
}
-
[:2] val transaction = supportFragmentManager.beginTransaction()
// androidx.fragment.app.FragmentManager public FragmentTransaction beginTransaction() { return new BackStackRecord(this); }
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord
classDiagram class FragmentTransaction class BackStackRecord class FragmentManager class `FragmentManager-BackStackEntry` class `FragmentManager-OpGenerator` BackStackRecord --|> FragmentTransaction: extends BackStackRecord --|> `FragmentManager-BackStackEntry`: impl BackStackRecord --|>` FragmentManager-OpGenerator`: impl FragmentManager --> BackStackRecord: create
-
[:3] transaction.add(R.id.content_fragment, Fragment2())
// androidx.fragment.app.FragmentTransaction public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment) { [:3:0] doAddOp(containerViewId, fragment, null, OP_ADD); return this; }
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add
其中
OP_ADD
⬇️ = 1// androidx.fragment.app.FragmentTransaction static final int OP_NULL = 0; static final int OP_ADD = 1; static final int OP_REPLACE = 2; static final int OP_REMOVE = 3; static final int OP_HIDE = 4; static final int OP_SHOW = 5; static final int OP_DETACH = 6; static final int OP_ATTACH = 7; static final int OP_SET_PRIMARY_NAV = 8; static final int OP_UNSET_PRIMARY_NAV = 9; static final int OP_SET_MAX_LIFECYCLE = 10;
-
[:3:0] doAddOp(containerViewId, fragment, null, OP_ADD)
// androidx.fragment.app.FragmentTransaction void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) { ... [:3:0:1] addOp(new Op(opcmd, fragment)); }
-
[:3:0:1] addOp(new Op(opcmd, fragment))
// androidx.fragment.app.FragmentTransaction void addOp(Op op) { mOps.add(op); ... }
// androidx.fragment.app.FragmentTransaction ArrayList<Op> mOps = new ArrayList<>();
classDiagram class FragmentTransaction { mOps: ArrayList<OP> } class BackStackRecord class FragmentManager class `FragmentManager-BackStackEntry` class `FragmentManager-OpGenerator` class `FragmentTransaction-Op` { mCmd: int mFragment: Fragment } BackStackRecord --|> FragmentTransaction: extends BackStackRecord --|> `FragmentManager-BackStackEntry`: impl BackStackRecord --|> `FragmentManager-OpGenerator`: impl FragmentManager --> BackStackRecord: create FragmentTransaction --> `FragmentTransaction-Op`: holds
FragmentTransaction
中有一个Op
list记录我们添加的操作——OP_ADD
-
[:4] transaction.commit()
// androidx.fragment.app.FragmentTransaction public abstract int commit();
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit
// androidx.fragment.app.BackStackRecord @Override public int commit() { return commitInternal(false); }
// androidx.fragment.app.BackStackRecord int commitInternal(boolean allowStateLoss) { ... [:4:0] mManager.enqueueAction(this, allowStateLoss); ... }
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction
-
[:4:0] mManager.enqueueAction(this, allowStateLoss);
// androidx.fragment.app.FragmentManager void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) { ... mPendingActions.add(action); [:4:0:0] scheduleCommit(); ... }
// androidx.fragment.app.FragmentManager private final ArrayList<OpGenerator> mPendingActions = new ArrayList<>();
// androidx.fragment.app.FragmentManager interface OpGenerator { /** * Generate transactions to add to {@code records} and whether or not the transaction is * an add or pop to {@code isRecordPop}. * * records and isRecordPop must be added equally so that each transaction in records * matches the boolean for whether or not it is a pop in isRecordPop. * * @param records A list to add transactions to. * @param isRecordPop A list to add whether or not the transactions added to records is * a pop transaction. * @return true if something was added or false otherwise. */ boolean generateOps(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop); }
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add
classDiagram class FragmentTransaction { mOps: ArrayList"OP" } class BackStackRecord class FragmentManager { mPendingActions: ArrayList"OpGenerator" } class `FragmentManager-BackStackEntry` class `FragmentManager-OpGenerator` class `FragmentTransaction-Op` { mCmd: int mFragment: Fragment } BackStackRecord --|> FragmentTransaction: extends BackStackRecord --|> `FragmentManager-BackStackEntry`: impl BackStackRecord --|> `FragmentManager-OpGenerator`: impl FragmentManager --> BackStackRecord: create FragmentTransaction --> `FragmentTransaction-Op`: holds FragmentManager --> `FragmentManager-OpGenerator`: holds
-
[:4:0:0] scheduleCommit();
// androidx.fragment.app.FragmentManager void scheduleCommit() { synchronized (mPendingActions) { ... [:4:0:0:0] mHost.getHandler().post(mExecCommit); ... }
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add FragmentManager ->> FragmentManager: scheduleCommit
-
[:4:0:0:0] mHost.getHandler().post(mExecCommit)
mExecCommit
⬇️被放入消息队列,之后会被执行。// androidx.fragment.app.FragmentManager private Runnable mExecCommit = new Runnable() { @Override public void run() { [:4:0:0:0:0] execPendjingActions(true); } };
-
[:4:0:0:0:0] execPendjingActions(true);
// androidx.fragment.app.FragmentManager boolean execPendingActions(boolean allowStateLoss) { ensureExecReady(allowStateLoss); [:4:0:0:0:0:0]while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) { mExecutingActions = true; try { [:4:0:0:0:0:1] removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop); ...
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add FragmentManager ->> FragmentManager: scheduleCommit FragmentManager ->> FragmentManager: execPendingActions
-
[:4:0:0:0:0:0] generateOpsForPendingActions(mTmpRecords, mTmpIsPop)
// androidx.fragment.app.FragmentManager private boolean generateOpsForPendingActions(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isPop) { ... for (int i = 0; i < numActions; i++) { [:4:0:0:0:0:0:0] didSomething |= mPendingActions.get(i).generateOps(records, isPop); } ... }
这里对
mPendingActions
中的每一个Action都调用generateOps
——会处理到之前在[:4:0]
添加的ActionsequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord participant OpGenerator MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add FragmentManager ->> FragmentManager: scheduleCommit FragmentManager ->> FragmentManager: execPendingActions FragmentManager ->> OpGenerator: generateOps OpGenerator ->> BackStackRecord: generateOps
classDiagram class FragmentTransaction { mOps: ArrayList"OP" } class BackStackRecord class FragmentManager { mPendingActions: ArrayList"OpGenerator" } class `FragmentManager-BackStackEntry` class `FragmentManager-OpGenerator` { boolean generateOps() } class `FragmentTransaction-Op` { mCmd: int mFragment: Fragment } BackStackRecord --|> FragmentTransaction: extends BackStackRecord --|> `FragmentManager-BackStackEntry`: impl BackStackRecord --|> `FragmentManager-OpGenerator`: impl FragmentManager --> BackStackRecord: create FragmentTransaction --> `FragmentTransaction-Op`: holds FragmentManager --> `FragmentManager-OpGenerator`: holds
-
[:4:0:0:0:0:0:0] mPendingActions.get(i).generateOps(records, isPop)
// androidx.fragment.app.BackStackRecord public boolean generateOps(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop) { ... records.add(this); ... }
BackStackRecord
将自己添加到传入的records
中 -
[:4:0:0:0:0:1] removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop)
遍历[:4:0:0:0:0:0]
返回的每一个record,对其处理// androidx.fragment.app.FragmentManager private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop) { ... final int numRecords = records.size(); for (int recordNum = 0; recordNum < numRecords; recordNum++) { ... int reorderingEnd = recordNum + 1; [:4:0:0:0:0:1:0] executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd); ... } }
遍历执行record,
executeOpsTogether(records
传入了整个records
——只有一个OP_ADD
,通过后面两个参数指定要执行的 record的开始位置和结束位置——recordNum(0)和reorderingEnd(recordNum + 1 = 0 + 1 = 1),也就相当于挨个执行。sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord participant OpGenerator MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add FragmentManager ->> FragmentManager: scheduleCommit FragmentManager ->> FragmentManager: execPendingActions FragmentManager ->> OpGenerator: generateOps OpGenerator ->> BackStackRecord: generateOps FragmentManager ->> FragmentManager: removeRedundantOperationsAndExecute
-
[:4:0:0:0:0:1:0] executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd)
// androidx.fragment.app.FragmentManager private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { ... [:4:0:0:0:0:1:0:0] executeOps(records, isRecordPop, startIndex, endIndex); ... [:4:0:0:0:0:1:0:1] fragmentStateManager.moveToExpectedState(); ... ...
startIndex
:recordNum
= 0
endIndex
:reorderingEnd
= 1 -
[:4:0:0:0:0:1:0:0] executeOps(records, isRecordPop, startIndex, endIndex);
// androidx.fragment.app.FragmentManager private static void executeOps(@NonNull ArrayList<BackStackRecord> records, @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) { for (int i = startIndex; i < endIndex; i++) { [:4:0:0:0:0:1:0:0:0] record.executeOps(); } } }
sequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord participant OpGenerator MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add FragmentManager ->> FragmentManager: scheduleCommit FragmentManager ->> FragmentManager: execPendingActions FragmentManager ->> OpGenerator: generateOps OpGenerator ->> BackStackRecord: generateOps FragmentManager ->> FragmentManager: removeRedundantOperationsAndExecute FragmentManager ->> FragmentManager: executeOpsTogether FragmentManager ->> FragmentManager: executeOps FragmentManager ->> BackStackRecord: executeOps
classDiagram class FragmentTransaction { mOps: ArrayList"OP" } class BackStackRecord { executeOps(): void } class FragmentManager { mPendingActions: ArrayList"OpGenerator" } class `FragmentManager-BackStackEntry` class `FragmentManager-OpGenerator` { boolean generateOps() } class `FragmentTransaction-Op` { mCmd: int mFragment: Fragment } BackStackRecord --|> FragmentTransaction: extends BackStackRecord --|> `FragmentManager-BackStackEntry`: impl BackStackRecord --|> `FragmentManager-OpGenerator`: impl FragmentManager --> BackStackRecord: create FragmentTransaction --> `FragmentTransaction-Op`: holds FragmentManager --> `FragmentManager-OpGenerator`: holds
-
[:4:0:0:0:0:1:0:0:0] record.executeOps();
// androidx.fragment.app.BackStackRecord void executeOps() { final int numOps = mOps.size(); for (int opNum = 0; opNum < numOps; opNum++) { switch (op.mCmd) { case OP_ADD: f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim); mManager.setExitAnimationOrder(f, false); [:4:0:0:0:0:1:0:0:0:0] mManager.addFragment(f); break;
mOps
的数量为1——[:3:0:1]
添加的OP_ADDsequenceDiagram autonumber participant MainActivity participant FragmentManager participant FragmentTransaction participant BackStackRecord participant OpGenerator MainActivity ->> FragmentManager: beginTransaction FragmentManager ->> FragmentTransaction: new FragmentManager ->> BackStackRecord: new FragmentManager ->> MainActivity: return (FragmentTransaction)BackStackRecord MainActivity ->> FragmentTransaction: add MainActivity ->> FragmentTransaction: commit FragmentTransaction ->> FragmentManager: enqueueAction FragmentManager ->> FragmentManager: mPendingActions.add FragmentManager ->> FragmentManager: scheduleCommit FragmentManager ->> FragmentManager: execPendingActions FragmentManager ->> OpGenerator: generateOps OpGenerator ->> BackStackRecord: generateOps FragmentManager ->> FragmentManager: removeRedundantOperationsAndExecute FragmentManager ->> FragmentManager: executeOpsTogether FragmentManager ->> FragmentManager: executeOps FragmentManager ->> BackStackRecord: executeOps BackStackRecord ->> FragmentManager: addFragment
-
[:4:0:0:0:0:1:0:0:0:0] mManager.addFragment(f);
// androidx.fragment.app.FragmentManager FragmentStateManager addFragment(@NonNull Fragment fragment) { if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "add: " + fragment); FragmentStateManager fragmentStateManager = createOrGetFragmentStateManager(fragment); fragment.mFragmentManager = this; mFragmentStore.makeActive(fragmentStateManager); if (!fragment.mDetached) { mFragmentStore.addFragment(fragment); fragment.mRemoving = false; if (fragment.mView == null) { fragment.mHiddenChanged = false; } if (isMenuAvailable(fragment)) { mNeedMenuInvalidate = true; } } return fragmentStateManager; }
-
[:4:0:0:0:0:1:0:1] fragmentStateManager.moveToExpectedState()
这里回到上面说过的[:1:0:0:1]