自学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生命周期回调

片段生命周期状态及其关系片段的生命周期回调和片段的视图生命周期

        注意: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)}.
     * <p>A default View can be returned by calling {@link #Fragment(int)} in your
     * constructor. Otherwise, this method returns null.
     *
     * <p>It is recommended to <strong>only</strong> inflate the layout in this method and move
     * logic that operates on the returned View to {@link #onViewCreated(View, Bundle)}.
     *
     * <p>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)}。
     * <p>可以通过调用 {@link #Fragment(int)} 返回默认视图
     * 构造函数。否则,此方法返回 null。
     *
     * <p>建议在此方法中<strong>只</strong>膨胀布局并移动
     * 对返回的视图进行操作的逻辑 {@link #onViewCreated(View, Bundle)}。
     *
     * <p>如果你从这里返回一个视图,你以后会被调用
     * {@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:
 * <ul>
 *     <li>after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;
 *     <li><b>right before</b> {@link android.app.Activity#onStop() onStop} call.
 * </ul>
 */
CREATED,

注释翻译:

/**
          * 为 LifecycleOwner 创建状态。 对于 {@link android.app.Activity},此状态
          * 在两种情况下达到:
          * <ul>
          * <li>{@link android.app.Activity#onCreate(android.os.Bundle) onCreate} 调用之后;
          * <li><b>就在</b> {@link android.app.Activity#onStop() onStop} 调用之前。
          * </ul>
          */

3、onViewCreated()

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

五、Handling Lifecycles

1、Handling Lifecycles

包含:

  • Lifecycle
  • LifecycleObserver
  • LifecycleOwner

2、LifecycleObserver

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

3、LifecycleOwner

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

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

评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值