返回

Fragment生命周期源码分析

Android

Fragment生命周期概述

Fragment的生命周期与Activity的生命周期紧密相关,当Activity被创建、销毁或暂停时,Fragment也会经历相应的生命周期。Fragment的生命周期主要包括以下几个阶段:

  • onAttach() :当Fragment被添加到Activity时调用。
  • onCreate() :当Fragment被创建时调用。
  • onCreateView() :当Fragment创建其视图时调用。
  • onActivityCreated() :当Fragment所在的Activity被创建时调用。
  • onStart() :当Fragment可见时调用。
  • onResume() :当Fragment获得焦点时调用。
  • onPause() :当Fragment失去焦点时调用。
  • onStop() :当Fragment不可见时调用。
  • onDestroyView() :当Fragment的视图被销毁时调用。
  • onDestroy() :当Fragment被销毁时调用。
  • onDetach() :当Fragment从Activity中移除时调用。

Fragment生命周期方法详解

onAttach()

onAttach()方法是在Fragment被添加到Activity时调用的。在这个方法中,Fragment可以获取到其所在的Activity对象。

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    this.activity = activity;
}

onCreate()

onCreate()方法是在Fragment被创建时调用的。在这个方法中,Fragment可以进行一些初始化操作,例如创建视图、绑定数据等。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 初始化视图
    View view = LayoutInflater.from(activity).inflate(R.layout.fragment_main, null);
    // 绑定数据
    TextView textView = view.findViewById(R.id.text_view);
    textView.setText("Hello World!");
}

onCreateView()

onCreateView()方法是在Fragment创建其视图时调用的。在这个方法中,Fragment可以返回一个View对象作为其视图。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // 创建视图
    View view = inflater.inflate(R.layout.fragment_main, container, false);
    // 绑定数据
    TextView textView = view.findViewById(R.id.text_view);
    textView.setText("Hello World!");
    return view;
}

onActivityCreated()

onActivityCreated()方法是在Fragment所在的Activity被创建时调用的。在这个方法中,Fragment可以获取到其所在的Activity的View对象。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // 获取Activity的View对象
    View view = getActivity().findViewById(R.id.activity_main);
    // 绑定数据
    TextView textView = view.findViewById(R.id.text_view);
    textView.setText("Hello World!");
}

onStart()

onStart()方法是在Fragment可见时调用的。在这个方法中,Fragment可以进行一些初始化操作,例如加载数据、启动线程等。

@Override
public void onStart() {
    super.onStart();
    // 加载数据
    loadData();
    // 启动线程
    startThread();
}

onResume()

onResume()方法是在Fragment获得焦点时调用的。在这个方法中,Fragment可以进行一些与用户交互的操作,例如处理点击事件、播放音乐等。

@Override
public void onResume() {
    super.onResume();
    // 处理点击事件
    Button button = getView().findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO: 处理点击事件
        }
    });
    // 播放音乐
    MediaPlayer mediaPlayer = MediaPlayer.create(activity, R.raw.music);
    mediaPlayer.start();
}

onPause()

onPause()方法是在Fragment失去焦点时调用的。在这个方法中,Fragment可以进行一些清理操作,例如停止线程、关闭数据库连接等。

@Override
public void onPause() {
    super.onPause();
    // 停止线程
    stopThread();
    // 关闭数据库连接
    closeDatabaseConnection();
}

onStop()

onStop()方法是在Fragment不可见时调用的。在这个方法中,Fragment可以进行一些资源释放操作,例如释放内存、取消网络请求等。

@Override
public void onStop() {
    super.onStop();
    // 释放内存
    releaseMemory();
    // 取消网络请求
    cancelNetworkRequests();
}

onDestroyView()

onDestroyView()方法是在Fragment的视图被销毁时调用的。在这个方法中,Fragment可以进行一些资源释放操作,例如释放视图中的资源等。

@Override
public void onDestroyView() {
    super.onDestroyView();
    // 释放视图中的资源
    releaseViewResources();
}

onDestroy()

onDestroy()方法是在Fragment被销毁时调用的。在这个方法中,Fragment可以进行一些资源释放操作,例如释放内存、取消网络请求等。

@Override
public void onDestroy() {
    super.onDestroy();
    // 释放内存
    releaseMemory();
    // 取消网络请求
    cancelNetworkRequests();
}

onDetach()

onDetach()方法是在Fragment从Activity中移除时调用的。在这个方法中,Fragment可以进行一些资源释放操作,例如释放视图中的资源等。

@Override
public void onDetach() {
    super.onDetach();
    // 释放视图中的资源
    releaseViewResources();
}

Fragment生命周期源码分析

Fragment的生命周期方法都是在Fragment类中定义的。这些方法的实现代码都非常简单,主要是调用Activity的相应方法。例如,onAttach()方法的实现代码如下:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    mFragmentManager = activity.getFragmentManager();
    mHost = activity;
}

从上面的代码可以看出,onAttach()方法首先调用父类的onAttach()方法,然后获取Activity的FragmentManager对象和Activity对象。

onCreate()方法的实现代码如下:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Restore state from saved instance
    Bundle args = getArguments();
    if (args != null) {
        mArguments = args;
        mSavedFragmentState = args.getParcelable(Fragment.ARGUMENT_STATE);
    } else {
        mArguments = new Bundle();
    }
    mCalled = false;

    mChildFragmentManager = new FragmentManagerImpl();
    mChildFragmentManager.attachController(mHost, new FragmentContainer() {
        @Override
        public View findViewById(int id) {
            if (mContainerView != null) {
                return mContainerView.findViewById(id);
            }
            return null;
        }
    }, this);
    if (mSavedFragmentState != null) {
        mChildFragmentManager.restoreAllState(mSavedFragmentState.getFragmentManagerState(),
                mSavedFragmentState.getLoaderManagerState());
    }
}

从上面的代码可以看出,onCreate()方法首先调用父类的onCreate()方法,然后恢复Fragment的状态、创建子FragmentManager对象。

onCreateView()方法的实现代码如下:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    if (mHost == null) {
        throw new IllegalStateException("Fragment has not been attached yet.");
    }
    if (mInLayout) {
        throw new IllegalStateException(
                "onCreateView() is called twice when Fragment should be detached.");
    }

    if (mLayoutInflater == null) {
        mLayoutInflater = inflater.cloneInContext(mHost);
    }

    int resId = mContainerId;
    if (resId == 0) {
        resId = mContentLayoutId;
    }
    if (resId == 0) {
        return null;
    }

    LayoutInflater.Factory2 factory = mLayoutInflater.getFactory2();
    mFragmentFactoryHost = factory instanceof FragmentFactoryHost ?
            (FragmentFactoryHost) factory : null;

    View parent = null;
    if (mContainer != null) {
        parent = mContainer;
    } else if (mContainerId != 0) {
        parent = (ViewGroup) mHost.findViewById(mContainerId);
    }
    mContainer = parent;
    return inflater.inflate