fragment
- android developer#fragments (opens new window)
- FragmentManagerImpl (opens new window)
- BackStackRecord (opens new window)
# 基础知识
Fragment是Android中的一个重要组件,代表Activity中的行为或用户界面的一部分。Fragment具有自己的生命周期,可以接收自己的输入事件,并且可以在Activity运行时添加或删除。
# Fragment状态定义
static final int INITIALIZING = 0; // 初始化状态
static final int CREATED = 1; // 已创建状态
static final int ACTIVITY_CREATED = 2; // Activity已创建状态
static final int STARTED = 3; // 已启动状态
static final int RESUMED = 4; // 已恢复状态
1
2
3
4
5
2
3
4
5
# Fragment基本操作
// 创建Fragment实例
MyFragment fragment = new MyFragment();
// 获取FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();
// 开始事务
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 添加Fragment
transaction.add(R.id.container, fragment, "tag");
// 替换Fragment
transaction.replace(R.id.container, fragment);
// 移除Fragment
transaction.remove(fragment);
// 隐藏Fragment
transaction.hide(fragment);
// 显示Fragment
transaction.show(fragment);
// 提交事务
transaction.commit();
// 或者立即执行
transaction.commitNow();
// 或者允许状态丢失
transaction.commitAllowingStateLoss();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Fragment生命周期回调
public class MyFragment extends Fragment {
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// Fragment首次附加到其Context时调用
// onCreate将在此之后调用
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Fragment被创建时调用
// 用于初始化Fragment
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
// 创建Fragment的视图层次结构
return inflater.inflate(R.layout.fragment_my, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// 在onCreateView之后调用
// 用于初始化视图组件
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Activity的onCreate方法完成后调用
// 可以安全地访问Activity的视图层次结构
}
@Override
public void onStart() {
super.onStart();
// Fragment变为可见时调用
}
@Override
public void onResume() {
super.onResume();
// Fragment变为可交互时调用
}
@Override
public void onPause() {
super.onPause();
// Fragment不再可交互时调用
}
@Override
public void onStop() {
super.onStop();
// Fragment不再可见时调用
}
@Override
public void onDestroyView() {
super.onDestroyView();
// Fragment的视图层次结构被销毁时调用
}
@Override
public void onDestroy() {
super.onDestroy();
// Fragment被销毁时调用
}
@Override
public void onDetach() {
super.onDetach();
// Fragment从其Context分离时调用
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 生命周期管理
# 状态向上转移过程
考虑如下代码,观察生命周期的走向
fragmentManager.beginTransaction()
// BackStackRecord
.add(container.getId(), fragment, tag)
.commitNowAllowingStateLoss();
1
2
3
4
2
3
4
# 状态转移详解
0 -> 1: 为mHost赋值
onAttach: Fragment首次附加到ContextonCreate: Fragment被创建
1 -> 2: 创建视图
onCreateView: 创建Fragment的视图层次结构onViewCreated: 视图创建完成后的初始化onActivityCreated: Activity创建完成restoreViewState: 如果可能,恢复视图状态
2 -> 3: 启动Fragment
onStart: Fragment变为可见
3 -> 4: 恢复Fragment
onResume: Fragment变为可交互
# onAttach详细分析
public void onAttach(@NonNull Context context): Called when a fragment is first attached to its context. onCreate will be called after this.
// FragmentManagerImpl#moveToState 的一段代码
if (newState > 0) {
// ...
if (f.mSavedFragmentState != null) {
// ...
}
// fragment的 mHost的赋值地方
f.mHost = this.mHost;
f.mParentFragment = this.mParent;
f.mFragmentManager = this.mParent != null ? this.mParent.mChildFragmentManager : this.mHost.getFragmentManagerImpl();
if (f.mTarget != null) {
if (this.mActive.get(f.mTarget.mIndex) != f.mTarget) {
throw new IllegalStateException("Fragment " + f + " declared target fragment " + f.mTarget + " that does not belong to this FragmentManager!");
}
if (f.mTarget.mState < 1) {
this.moveToState(f.mTarget, 1, 0, 0, true);
}
}
this.dispatchOnFragmentPreAttached(f, this.mHost.getContext(), false);
f.mCalled = false;
// onAttach 先调用
f.onAttach(this.mHost.getContext());
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
this.mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
this.dispatchOnFragmentAttached(f, this.mHost.getContext(), false);
if (!f.mIsCreated) {
this.dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
// 回调onCreate
f.performCreate(f.mSavedFragmentState);
this.dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = 1;
}
f.mRetaining = false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# isAdded返回值
- return false
onAttachonCreate
- return true
onCreateViewonViewCreatedonActivityCreatedonStartonResume
# Fragment管理器
# getFragmentManager vs getChildFragmentManager
# 1. getFragmentManager()
定义
- 方法:
Fragment.getFragmentManager() - 返回:宿主Activity的FragmentManager
用途
- 用于在Fragment中访问宿主Activity的FragmentManager
- 通常用于管理直接附加到Activity的顶层Fragment
场景
- 在Activity中添加、替换、删除Fragment
- 在一个Fragment中操作同级的其他顶层Fragment
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.container, new ExampleFragment());
transaction.commit();
1
2
3
4
2
3
4
# 2. getChildFragmentManager()
定义
- 方法:
Fragment.getChildFragmentManager() - 返回:当前Fragment的内部FragmentManager
用途
- 用于在Fragment中嵌套子Fragment
- 适合在Fragment内部管理其子Fragment的生命周期和操作
场景
- 当需要嵌套Fragment时(Fragment内的Fragment)
- 子Fragment的生命周期会跟随父Fragment,而不是宿主Activity
FragmentManager childFragmentManager = getChildFragmentManager();
FragmentTransaction transaction = childFragmentManager.beginTransaction();
transaction.add(R.id.child_container, new ChildFragment());
transaction.commit();
1
2
3
4
2
3
4
# Fragment事务管理
// 基本事务操作
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 添加Fragment到回退栈
transaction.addToBackStack("fragment_tag");
// 设置过渡动画
transaction.setCustomAnimations(
R.anim.slide_in_right,
R.anim.slide_out_left,
R.anim.slide_in_left,
R.anim.slide_out_right
);
// 设置事务优先级
transaction.setReorderingAllowed(true);
// 提交事务的不同方式
transaction.commit(); // 异步提交
transaction.commitNow(); // 同步提交
transaction.commitAllowingStateLoss(); // 允许状态丢失的提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 数据传递与通信
# Fragment间数据传递
# 1. 使用Bundle传递数据
// 创建Fragment并传递参数
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString("key", "value");
args.putInt("number", 123);
fragment.setArguments(args);
// 在Fragment中接收参数
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
String value = getArguments().getString("key");
int number = getArguments().getInt("number");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2. 使用ViewModel共享数据
// 创建共享ViewModel
public class SharedViewModel extends ViewModel {
private final MutableLiveData<String> selected = new MutableLiveData<>();
public void select(String item) {
selected.setValue(item);
}
public LiveData<String> getSelected() {
return selected;
}
}
// 在Fragment中使用
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), item -> {
// 处理选中的项目
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 3. Fragment结果API
// 设置结果监听器
setFragmentResultListener("requestKey", this, (requestKey, bundle) -> {
String result = bundle.getString("bundleKey");
// 处理结果
});
// 发送结果
Bundle result = new Bundle();
result.putString("bundleKey", "result");
setFragmentResult("requestKey", result);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Fragment与Activity通信
# 1. 接口回调
// 定义接口
public interface OnFragmentInteractionListener {
void onFragmentInteraction(String data);
}
// 在Fragment中
public class MyFragment extends Fragment {
private OnFragmentInteractionListener mListener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
}
}
private void sendDataToActivity(String data) {
if (mListener != null) {
mListener.onFragmentInteraction(data);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2. 使用Activity的ViewModel
// 在Activity中
public class MainActivity extends AppCompatActivity {
private MainViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
}
}
// 在Fragment中
MainViewModel viewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class);
viewModel.getData().observe(getViewLifecycleOwner(), data -> {
// 处理数据
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 高级特性
# Fragment工厂模式
// 使用Fragment工厂创建Fragment
public class MyFragmentFactory extends FragmentFactory {
@Override
public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
if (className.equals(MyFragment.class.getName())) {
return new MyFragment();
}
return super.instantiate(classLoader, className);
}
}
// 在Activity中设置
getSupportFragmentManager().setFragmentFactory(new MyFragmentFactory());
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Fragment状态保存与恢复
public class MyFragment extends Fragment {
private String savedData;
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("saved_data", savedData);
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState != null) {
savedData = savedInstanceState.getString("saved_data");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Fragment懒加载
public abstract class LazyFragment extends Fragment {
private boolean isViewCreated = false;
private boolean isDataLoaded = false;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
isViewCreated = true;
loadDataIfNeeded();
}
@Override
public void onResume() {
super.onResume();
loadDataIfNeeded();
}
private void loadDataIfNeeded() {
if (isViewCreated && getUserVisibleHint() && !isDataLoaded) {
loadData();
isDataLoaded = true;
}
}
protected abstract void loadData();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 常见问题与解决方案
# 1. Fragment has not been attached yet
错误信息
java.lang.IllegalStateException: Fragment has not been attached yet.
android.support.v4.app.Fragment.instantiateChildFragmentManager(Fragment.java:2383)
android.support.v4.app.Fragment.getChildFragmentManager(Fragment.java:845)
1
2
3
2
3
原因分析
- 过早调用
getChildFragmentManager()方法 - Fragment的
mHost字段为null - Fragment尚未完成附加过程
解决方案
// 检查Fragment是否已附加
if (isAdded()) {
FragmentManager childFragmentManager = getChildFragmentManager();
// 执行Fragment操作
}
// 或者在onAttach之后调用
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// 现在可以安全地使用getChildFragmentManager()
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 2. Fragment状态丢失
问题描述
- Fragment在配置更改时丢失状态
- 数据未正确保存和恢复
解决方案
// 使用ViewModel保存数据
public class MyViewModel extends ViewModel {
private final MutableLiveData<String> data = new MutableLiveData<>();
public LiveData<String> getData() {
return data;
}
public void setData(String value) {
data.setValue(value);
}
}
// 在Fragment中使用
private MyViewModel viewModel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 3. Fragment重叠问题
问题描述
- 多个Fragment同时显示
- Fragment视图重叠
解决方案
// 使用replace而不是add
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.addToBackStack(null);
transaction.commit();
// 或者在添加前检查是否已存在
if (fragmentManager.findFragmentByTag("tag") == null) {
transaction.add(R.id.container, fragment, "tag");
transaction.commit();
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4. Fragment生命周期混乱
问题描述
- Fragment生命周期回调顺序异常
- 在错误的生命周期阶段执行操作
解决方案
// 使用getViewLifecycleOwner()观察LiveData
viewModel.getData().observe(getViewLifecycleOwner(), data -> {
// 处理数据更新
});
// 检查Fragment状态
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getView() != null) {
// 安全地操作视图
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 5. Fragment事务提交失败
问题描述
commit()调用后Fragment未显示- 事务被延迟执行
解决方案
// 使用commitNow()立即执行
transaction.commitNow();
// 或者检查Activity状态
if (!isStateSaved()) {
transaction.commit();
} else {
transaction.commitAllowingStateLoss();
}
// 在onCreate中延迟提交
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
// 执行Fragment操作
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 6. Fragment内存泄漏
问题描述
- Fragment持有Activity或Context引用
- 异步操作未正确取消
解决方案
// 使用弱引用
private WeakReference<Context> contextRef;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
contextRef = new WeakReference<>(context);
}
// 取消异步操作
@Override
public void onDestroy() {
super.onDestroy();
// 取消所有异步操作
if (asyncTask != null) {
asyncTask.cancel(true);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 最佳实践
# 1. Fragment设计原则
- 单一职责: 每个Fragment只负责一个功能
- 可重用性: 设计Fragment时考虑复用性
- 状态管理: 使用ViewModel管理Fragment状态
- 生命周期感知: 正确处理生命周期回调
# 2. 性能优化
// 使用Fragment工厂
public class MyFragmentFactory extends FragmentFactory {
@Override
public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
// 自定义Fragment创建逻辑
return super.instantiate(classLoader, className);
}
}
// 延迟加载
public class LazyFragment extends Fragment {
private boolean isDataLoaded = false;
@Override
public void onResume() {
super.onResume();
if (!isDataLoaded && getUserVisibleHint()) {
loadData();
isDataLoaded = true;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 3. 错误处理
// 统一的错误处理
public abstract class BaseFragment extends Fragment {
protected void handleError(Throwable throwable) {
// 统一的错误处理逻辑
Log.e("BaseFragment", "Error occurred", throwable);
showErrorDialog(throwable.getMessage());
}
protected void showErrorDialog(String message) {
new AlertDialog.Builder(requireContext())
.setTitle("错误")
.setMessage(message)
.setPositiveButton("确定", null)
.show();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 4. 测试策略
// Fragment单元测试
@RunWith(AndroidJUnit4.class)
public class MyFragmentTest {
@Test
public void testFragmentCreation() {
MyFragment fragment = new MyFragment();
assertNotNull(fragment);
}
@Test
public void testFragmentLifecycle() {
// 测试Fragment生命周期
FragmentScenario<MyFragment> scenario = FragmentScenario.launch(MyFragment.class);
scenario.onFragment(fragment -> {
// 验证Fragment状态
assertTrue(fragment.isAdded());
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 实际应用案例
# 1. 主从Fragment模式
// 主Fragment
public class MasterFragment extends Fragment {
private OnItemSelectedListener listener;
public interface OnItemSelectedListener {
void onItemSelected(String item);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof OnItemSelectedListener) {
listener = (OnItemSelectedListener) context;
}
}
private void onItemClick(String item) {
if (listener != null) {
listener.onItemSelected(item);
}
}
}
// 从Fragment
public class DetailFragment extends Fragment {
public static DetailFragment newInstance(String item) {
DetailFragment fragment = new DetailFragment();
Bundle args = new Bundle();
args.putString("item", item);
fragment.setArguments(args);
return fragment;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 2. 标签页Fragment
// 使用ViewPager2和TabLayout
public class TabFragment extends Fragment {
private ViewPager2 viewPager;
private TabLayout tabLayout;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab, container, false);
viewPager = view.findViewById(R.id.viewPager);
tabLayout = view.findViewById(R.id.tabLayout);
setupViewPager();
setupTabLayout();
return view;
}
private void setupViewPager() {
FragmentAdapter adapter = new FragmentAdapter(this);
viewPager.setAdapter(adapter);
}
private void setupTabLayout() {
TabLayoutMediator mediator = new TabLayoutMediator(tabLayout, viewPager,
(tab, position) -> tab.setText("Tab " + (position + 1)));
mediator.attach();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 3. 对话框Fragment
// 自定义对话框Fragment
public class CustomDialogFragment extends DialogFragment {
public static CustomDialogFragment newInstance(String title) {
CustomDialogFragment fragment = new CustomDialogFragment();
Bundle args = new Bundle();
args.putString("title", title);
fragment.setArguments(args);
return fragment;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String title = getArguments().getString("title");
return new AlertDialog.Builder(requireContext())
.setTitle(title)
.setMessage("这是一个自定义对话框")
.setPositiveButton("确定", (dialog, which) -> {
// 处理确定按钮点击
})
.setNegativeButton("取消", null)
.create();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
分析一切的来源都是FragmentActivity持有的FragmentController对象!过早调用有可能出现此问题,需要保证mHost != null
上次更新: 2025/10/08, 16:24:59