绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
【Jetpack更新之Fragment】1.3.0-alpha04 来袭,Fragment 间通信的新姿势
2020-04-30 03:38:01

前言

fragment 1.3.0-alpha04 发布了,其中有很多变动,其中提供了 fragment 间传递数据的新方式

1.3.0-alpha04 更新
1.3.0-alpha04 更新

API 更改

首先我们介绍一下 API 更改

  • startActivityForResult()/onActivityResult()requestPermissions()/onRequestPermissionsResult() 弃用
  • prepareCall() 重命名为 registerForActivityResult()
  • target fragment API 被弃用

Activity Result API 上位

由于官方提供了 Activity Result API 来替换 onActivityResult 机制,因此 fragment 的 startActivityForResult()/onActivityResult()requestPermissions()/onRequestPermissionsResult() 方法被标记弃用了

Activity Result API 详情可参考 秉心说是时候丢掉 onActivityResult 了 !

文章介绍的很详尽,这里不再赘述

prepareCall 重命名

值得注意的地方是 prepareCall() 被命名为 registerForActivityResult()

注意:在版本处于 Alpha 版状态时,可以添加、移除或更改 API。因此 Alpha 版本不适合在生产上使用

来自我的另一篇博客
来自我的另一篇博客

target fragment API 被弃用

其实 target fragment API 早已被弃用

setTargetFragment 被弃用
setTargetFragment 被弃用

target fragment 需要直接访问另一个 fragment 的实例,这是十分危险的,因为你不知道目标 fragment 处于什么状态。而且 target fragment 不支持 Navigation

弃用 target fragment API
弃用 target fragment API

那么,fragment 之间传递数据更干净的方式是什么呢?

fragment 之间传递数据的新方式

前文提到,在相同的 FragmentManager 中可以使用 target fragment API 来在 fragment 间传递数据,但这种方式需要直接访问目标 fragment 的实例,这很危险,因为目标 fragment 的状态是未知的

因此官方提供了这样的 API,它允许在一个 fragment 上设置结果,并将该结果在 fragment 的适当的生命周期中使用。

这种传递数据的方式适用于 DialogFragment ,Navigation 中的 fragment

此更改还包括 -ktx 扩展功能以确保 kotlin 用户可以将 FragmentResultListener 作为 lambda 传递

FragmentA 源码
FragmentA 源码
FragmentB 源码
FragmentB 源码
demo
demo

源码分析

老规矩,我们沿着官方的 commit log 来看看官方实现该功能的思路

首先,添加了 FragmentResultOwner 这样的的抽象,用于处理 fragment result,其内部有两个方法

  • setResult
  • setResultListener

前者用于发送数据,后者用于接收数据

FragmentResultOwner
FragmentResultOwner

而其实现类为 FragmentManager

FragmentManager implement FragmentResultOwner
FragmentManager implement FragmentResultOwner

我们来看看 FragmentManager 两个方法的具体实现

public final void setFragmentResultListener(@NonNull final String requestKey,
        @NonNull final LifecycleOwner lifecycleOwner,
        @Nullable final FragmentResultListener listener)
 
{
    // 设置的 listener 为空时将 requestKey 对应的 listener 移除
    if (listener == null) {
        mResultListeners.remove(requestKey);
        return;
    }

    // 当fragment 处于DESTROYED 状态时 直接 return ,避免了异常
    final Lifecycle lifecycle = lifecycleOwner.getLifecycle();
    if (lifecycle.getCurrentState() == Lifecycle.State.DESTROYED) {
        return;
    }

    // 观察生命周期,fragment started 后接收回调,destroyed 移除回调
    LifecycleEventObserver observer = new LifecycleEventObserver() {
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event)
 
{
            if (event == Lifecycle.Event.ON_START) {
                // once we are started, check for any stored results
                Bundle storedResult = mResults.get(requestKey);
                if (storedResult != null) {
                    // if there is a result, fire the callback
                    listener.onFragmentResult(requestKey, storedResult);
                    // and clear the result
                    setFragmentResult(requestKey, null);
                }
            }
            if (event == Lifecycle.Event.ON_DESTROY) {
                lifecycle.removeObserver(this);
                mResultListeners.remove(requestKey);
            }
        }
    };
    lifecycle.addObserver(observer);
    mResultListeners.put(requestKey, new LifecycleAwareResultListener(lifecycle, listener));
}
复制代码

以上便是这部分的源码

这里要注意一点的是 fragment result api 是基于同一 FragmentManager

总结

官方一直致力于将 fragment 的 api 变得更好用

Ian LakeFragments: Past, Present, and Future (Android Dev Summit '19) 中提到了 fragment 间通信的问题,未来 fragment 会整合 fragment 自身和其内部 view 的生命周期,提供同一 FragmentManager 多返回栈的支持

看到 fragment result API ,我突然有个想法,如果将其应用到 Navigation 中是否是解决 Navigation 跳转返回后状态重置的一个方法呢?

各位小伙伴有什么想法欢迎评论区留言

关于我

我是 Fly_with24

分享好友

分享这个小栈给你的朋友们,一起进步吧。

Elasticsearch
创建时间:2020-05-22 14:49:51
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 栈栈
    专家
戳我,来吐槽~