讨论了两年的 Navigation 保存 Fragment 状态问题居然被关闭了

2021-03-12 15:45:30 +08:00
 lear7

讨论地址

https://github.com/android/architecture-components-samples/issues/530

问题描述

大概两年前开始使用 Navigation,当时觉得把所有 Fragment 都保存在一个导航图的理念很先进,然后就用了,然后发现每次 Fragment 都会重新创建,如果从 A 页面到 B 页面,然后返回 A 页面,那么 A 页面会被重建,FragmentA - FragmentB - New FragmentA,无论用户还是开发者都是不希望页面被重建的,https://github.com/android/architecture-components-samples/issues/530#issuecomment-658360926

Workaround

于是有了这位同学的解决方法,https://github.com/android/architecture-components-samples/issues/530#issuecomment-526455102

public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args,
            @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) {
        
//      ft.replace(mContainerId, frag);

//      change to  

        if(mFragmentManager.getFragments().size()>0){
            ft.hide(mFragmentManager.getFragments().get(mFragmentManager.getFragments().size()-1));
            ft.add(mContainerId, frag);
        }else {
            ft.replace(mContainerId, frag);
        }
        
}

于是就这样用了一年多,但是这个方法用起来也确实会有很多内存消耗问题,而且在非主流配置的机器上,页面跳转明显比官方的 Navigate()方法响应慢。

问题照旧

于是又翻了下这个问题的讨论情况,发现还是老样子,官方坚持说这么做会消耗大量内存,https://github.com/android/architecture-components-samples/issues/530#issuecomment-789131002 说这里是给你讨论我的 sample 代码的 issue 的,不是讨论 library 本身的??还坚持说我 Fragment 也没问题(没有任何人报告 issue ),各种保存和恢复机制都给你做好了等等等等,然后把问题关了??

请问下有用使用 Navigation 的同学吗?请说说你们的看法,谢谢!

11693 次点击
所在节点    Android
15 条回复
Lin0936
2021-03-12 16:00:13 +08:00
在用 navigation,用 viewmodel 保存状态,UI 重建无所谓
fragment 本身就挺垃圾😂
james2013
2021-03-12 18:15:38 +08:00
使用 Navigation 后,发现 A 界面是复杂的 fragment,返回到 A 界面重建时间耗费太长。而且 A 界面的 ViewModel 的数据又会重新更新一遍...
直接放弃使用了.
shily
2021-03-12 18:50:13 +08:00
直接弃用了,改回跳转 Activity 了。每次跳转回来时界面闪一下,不能接受。
yumerdev93
2021-03-13 08:07:31 +08:00
上面 show hide 的解决方法用了一年了,基本没问题。viewmodel 保存状态是个不错的方案,但是我不太喜欢😂
ikas
2021-03-13 21:07:19 +08:00
用 show,hide 也有很多问题,1.view 的层级问题,先 show 的 view 在下面,当你在次需要显示时,实际他是在新页面的下面,尤其做 xy 轴动画,可以明显看到.2.生命周期问题,hide 的视图,本身生命周期并没有任何改变,所以需要你配置最大生命周期,当设置为 STARTED 时会导致动画执行是在 RESUMED 之后.导致刷新数据造成动画卡顿,还会会导致 viewmodel 的监听不正常,如果设置为 CREATED,又会导致 view 重建..然后其他小问题就不说了..反正坑.官方说内存问题,就很搞笑啊,当内存不够时再销毁 fragment 不行么..就连 uwp 的 page 都支持 NavigationCacheMode(Disabled, Enabled, Required);目前我是自己实现了这样的东西,但是已经不想用了
slyang5
2021-03-13 21:50:52 +08:00
fragment 这个组件 简直就是 垃圾中的垃圾 ,30%的 crash 和它有关
cgpiao
2021-03-14 00:34:03 +08:00
字节不是创建了导航库吗,可以用那个。叫 scene, 官方 navigation 我觉得是半成品,包括 fragment 。
sankemao
2021-03-14 11:32:07 +08:00
google 的 api 向来很难用,比如 paging3
lear7
2021-03-15 09:10:59 +08:00
@ikas 我没怎么用到动画,当普通使用都会发现这个问题,所以页面统统不能设置透明的,不然会上一个页面会透出来。而且右上角的 optionmenu 也需要每个页面重新清空和增加,不然也会显示错乱。
lear7
2021-03-15 09:11:17 +08:00
@cgpiao 好的,感谢分享,我去了解一下!
zhanlanhuizhang
2021-03-15 20:23:14 +08:00
我也有这个问题。但是仔细研究后,可以重写 FragmentNavigator 下的 navigate 方法,然后重写 NavHostFragment 下的 onCreateNavController 方法。就可以自己想怎么控制,就怎么控制,虽然还是坑。
zhanlanhuizhang
2021-03-15 20:25:14 +08:00
我这里是配合 BottomNavigationView 一起用,所以网上的方法不管用,最后需要自己研究。
ikas
2021-03-15 23:23:31 +08:00
@zhanlanhuizhang 是重写,但是他这个问题不仅仅是 FragmentNavigator 问题,还有 Fragment 等的问题,目前基本都是重写,用 show,hide,但是 show,hide 根本不足以满足,还需要配合生命周期.....反正解决一个问题又来一个问题,然后发现越来越复杂了
ikas
2021-03-15 23:25:52 +08:00
@lear7 只用 show,hide,应该是没法解决这个问题了.目前想参考 viewpager2 来实现,但是本质 Fragment 的复杂,还是可预见的一堆问题
lisongeee
2022-05-15 01:03:48 +08:00
最近在用 Android Compose 的 navigation ,也是会出现这种情况,从页面 A 跳转到页面 B ,然后调用 navController.popBackStack 返回,页面 A 的所有状态都重置了,这个 compose 的开发理念和前端 react 的 hooks 基本一致,但是在 kotlin 语法糖的加持下,个人感觉开发效率比 react hooks 高,但是 react-router 也是和 compsoe 一样,路由 /栈 回退就会重新重建,除了路由参数还在,你啥都不能保存,除非你把这个页面所有的状态保存在上一个层级。但是 vue-router 就有 keep-alive ,可以缓存之前的状态,md ,这咋就这么难用呢,就不能延续之前的多 activity 模式吗,新建一个栈的时候,直接覆盖渲染,底下的栈直接停止更新渲染不行?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/761060

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX