自学Android开发 Fragment的onActivityCreated()被弃用

目录

一、Fragment的生命周期

1、Lifecycle状态及其与Fragment生命周期回调

二、onActivityCreated的弃用

1、官方更新文档

2、onViewCreated()和onCreateView()

2.1、onCreateView()源码

2.2、onViewCreated()源码

三、onActivityCreated方法

四、onActivityCreated弃用后的替代方案

1、替代方案

2、通过Lifecycles获取Activity的onCreate()事件

五、Handling Lifecycles

1、Handling Lifecycles

2、LifecycleObserver

3、LifecycleOwner


一、Fragment的生命周期

1、Lifecycle状态及其与Fragment生命周期回调

自学Android开发 Fragment的onActivityCreated()被弃用_第1张图片

        注意:onAttach()始终在任何Lifecycle 状态更改之前调用,所以onAttach()onCreate()之前调用。

二、onActivityCreated的弃用

1、官方更新文档

版本 1.3.0-alpha02

2020 年 3 月 18 日

发布了 androidx.fragment:fragment:1.3.0-alpha02androidx.fragment:fragment-ktx:1.3.0-alpha02 和 androidx.fragment:fragment-testing:1.3.0-alpha02。。

新功能

  • 添加了对 Activity 1.2.0-alpha02 中引入的 ActivityResultRegistry API 的支持,让您无需覆盖 Fragment 中的方法,即可处理 startActivityForResult()+onActivityResult() 以及 requestPermissions()+onRequestPermissionsResult() 流程,并提供用于测试这些流程的钩子。请参阅更新后的获取 Activity 的结果一文。

API 变更

  • DialogFragment 现在提供了一个采用 @LayoutRes 的构造函数,后者用于指明默认情况下 onCreateView() 应该膨胀的布局。
  • onActivityCreated() 方法现已弃用。与 Fragment 视图有关的代码应在 onViewCreated()(在 onActivityCreated() 之前调用)中执行,而其他初始化代码应在 onCreate() 中执行。如需专门在 Activity 的 onCreate() 完成时接收回调,应在 onAttach() 中的 Activity 的 Lifecycle 上注册 LifeCycleObserver,并在收到 onCreate() 回调后将其移除。

bug 修复

  • 从 Fragment 1.2.3 开始:修复了从 onCreateDialog() 内调用 getLayoutInflater() 时,DialogFragment 中导致 StackOverflowError 的错误。

  • 从 Fragment 1.2.3 开始:缩小了 Fragment 包含的 ProGuard 规则的范围,以确保可以剥离未使用的 Fragment 类。
  • 从 Fragment 1.2.3 开始:修复了在使用覆盖 Kotlin 属性名称的局部变量名称时,UseRequireInsteadOfGet Lint 检查中的误报问题。
  • 从 Fragment 1.2.3 开始:FragmentContainerView 不再因为在布局预览中使用不正确的构造函数而抛出 UnsupportedOperationException。

已知问题

  • BottomSheetDialogFragment 无法再在屏幕上正确定位其对话框。

2、onViewCreated()onCreateView()

        通过最新的Fragment的生命周期图可知onViewCreated()是在onCreateView()之后调用;

2.1、onCreateView()源码

 /**
     * Called to have the fragment instantiate its user interface view.
     * This is optional, and non-graphical fragments can return null. This will be called between
     * {@link #onCreate(Bundle)} and {@link #onViewCreated(View, Bundle)}.
     * 

A default View can be returned by calling {@link #Fragment(int)} in your * constructor. Otherwise, this method returns null. * *

It is recommended to only inflate the layout in this method and move * logic that operates on the returned View to {@link #onViewCreated(View, Bundle)}. * *

If you return a View from here, you will later be called in * {@link #onDestroyView} when the view is being released. * * @param inflater The LayoutInflater object that can be used to inflate * any views in the fragment, * @param container If non-null, this is the parent view that the fragment's * UI should be attached to. The fragment should not add the view itself, * but this can be used to generate the LayoutParams of the view. * @param savedInstanceState If non-null, this fragment is being re-constructed * from a previous saved state as given here. * * @return Return the View for the fragment's UI, or null. */ @MainThread @Nullable public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { if (mContentLayoutId != 0) { return inflater.inflate(mContentLayoutId, container, false); } return null; }

注释翻译

/**
     * 调用以使片段实例化其用户界面视图
     * 这是可选的,非图形片段可以返回 null。这将在
     * {@link #onCreate(Bundle)} 和 {@link #onViewCreated(View, Bundle)}。
     *

可以通过调用 {@link #Fragment(int)} 返回默认视图
     * 构造函数。否则,此方法返回 null。
     *
     *

建议在此方法中膨胀布局并移动
     * 对返回的视图进行操作的逻辑 {@link #onViewCreated(View, Bundle)}。
     *
     *

如果你从这里返回一个视图,你以后会被调用
     * {@link #onDestroyView} 当视图被释放时。
     *
     * @param inflater 可用于膨胀的 LayoutInflater 对象
     * 片段中的任何视图,
     * @param container 如果非空,这是片段的父视图
     * UI 应附加到。该片段不应添加视图本身,
     * 但这可用于生成视图的 LayoutParams。
     * @param savedInstanceState 如果非空,则此片段正在重新构造
     * 来自此处给出的先前保存的状态。
     *
     * @return 返回片段 UI 的视图,或者为 null。
     */

        注意:在使用LayoutInflater inflater实例化视图时,建议使用inflater.inflate(R.layout.xxx,container,false),不建议把ViewGroup 置null(inflater.inflate(R.layout.xxx,null,false))

2.2、onViewCreated()源码

 /**
     * Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
     * has returned, but before any saved state has been restored in to the view.
     * This gives subclasses a chance to initialize themselves once
     * they know their view hierarchy has been completely created.  The fragment's
     * view hierarchy is not however attached to its parent at this point.
     * @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
     * @param savedInstanceState If non-null, this fragment is being re-constructed
     * from a previous saved state as given here.
     */
    @MainThread
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    }

注释翻译

/**
      * 在 {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} 之后立即调用
      * 已经返回,但在任何保存的状态恢复到视图之前。
      * 这给了子类一次初始化自己的机会
      * 他们知道他们的视图层次结构已经完全创建。 片段的
      * 然而,此时视图层次结构并未附加到其父级。
      * @param view {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} 返回的视图。
      * @param savedInstanceState 如果非空,则此片段正在重新构造
      * 来自此处给出的先前保存的状态。
      */

        提示:一般onCreateView()用于初始化Fragment的视图,onViewCreated()一般用于初始化视图内各个控件,而onCreate()用于初始化与Fragment视图无关的变量。

三、onActivityCreated方法

        onActivityCreated()是在宿主Activity的onCreate()完成之后立即调用,这也确保了宿主Activity的视图是完成了初始化。当然在这个方法内也可以操作宿主Activity视图的控件View或者获知其他Fragment。

        执行该方法时,与Fragment绑定的Activity的onCreate()方法已经执行完成并返回,在onActivityCreated()内可以进行与Activity交互的UI操作,所以在onActivityCreated()之前Activity的onCreate方法并未执行完成,如果提前进行交互操作,会引发空指针异常。

        在旧的的API中onActivityCreated()常用用于初始化非静态的VIew控件(自定义VIew),静态控件不一定在onActivityCreated()中初始化,在onCreateView()onViewCreated()中初始化非静态的VIew控件都是错误的操作。

四、onActivityCreated弃用后的替代方案

1、替代方案

        谷歌为了管理Fragment的生命周期,实现了 LifecycleOwner,暴露了一个Lifecycle你可以通过getLifecycle() 方法访问的对象 。

        因为onActivityCreated()是宿主Activity的onCreate()之后立即调用,所以可以在onAttach的时候,通过订阅Activity的lifecycle来获取Activity的onCreate()事件,记得要removeObserver。

2、通过Lifecycles获取Activity的onCreate()事件

 @Override
    public void onAttach(@NonNull @NotNull Context context) {
        super.onAttach(context);

      //requireActivity() 返回的是宿主activity
       requireActivity().getLifecycle().addObserver(new LifecycleEventObserver() {
           @Override
           public void onStateChanged(@NonNull @NotNull LifecycleOwner source, @NonNull @NotNull Lifecycle.Event event) {
                if (event.getTargetState() == Lifecycle.State.CREATED){
                  //在这里任你飞翔
                    
                   requireActivity().getLifecycle().removeObserver(this);  //这里是删除观察者
                }
           }
       });
    }

提示:

/**
 * Created state for a LifecycleOwner. For an {@link android.app.Activity}, this state
 * is reached in two cases:
 * 
    *
  • after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call; *
  • right before {@link android.app.Activity#onStop() onStop} call. *
*/ CREATED,

注释翻译:

/**
          * 为 LifecycleOwner 创建状态。 对于 {@link android.app.Activity},此状态
          * 在两种情况下达到:
          *


              *
  • {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} 调用之后;
              *
  • 就在 {@link android.app.Activity#onStop() onStop} 调用之前。
              *

          */

3、onViewCreated()

在普通一般初始化View 时 已经可以替代onActivityCreated();

五、Handling Lifecycles

1、Handling Lifecycles

包含:

  • Lifecycle
  • LifecycleObserver
  • LifecycleOwner

2、LifecycleObserver

  • 具有Android生命周期的接口
  • 可以处理生命周期带来的变化却不需要在Activity或者Fragment中实现任何代码。

3、LifecycleOwner

  • 这是一个接口,用于将一个类标记为LifecycleObserver
  • 接口里面没有任何方法,而是依赖于 {@lOnLifecycleEvent}注释方法。

如果对您有一些意义,希望您给博主一些鼓励(点赞、关注、收藏),如果有错误欢迎大家评论。

你可能感兴趣的:(Android,开发,移动开发,android)