热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

重新加载Fragment时不会破坏范围为Fragment的ViewModel

我的应用允许用户提交表单(AndroidxFragment)以保存数据。提交表单约30次后,应

我的应用允许用户提交表单(Androidx Fragment)以保存数据。提交表单约30次后,应用程序内存不足并崩溃。内存转储的比较表明,问题的根源之一是提交表单时,与表单片段相关联的ViewModel并未被破坏。

使用片段的onViewCreated()方法中的'this'关键字,当前将ViewModel的作用域限定为片段:

vm = new ViewModelProvider(this).get(AddInventoryVM.class);

当用户提交表单时,通过使用“ Android体系结构组件”中的“ Android导航”来导航到同一片段,从而重新加载该片段。

navController.navigate(R.id.addInventoryFragment,null);

在此过渡期间,不会对ViewModel的实例进行垃圾回收。 onViewCreated()被调用并创建ViewModel的新实例-多次发生时会导致内存问题。不会调用'onDestroy()',但是在过渡期间会调用onDestroyView()

原因可能是Fragment实例在过渡期间未销毁(导致未对ViewModel进行垃圾回收)-仅销毁了Fragment的视图。但是,如果是这种情况,则不会增加任何东西-Android不会在过渡时重用现有的ViewModel而不是创建新的ViewModel吗?

尽管存在上述差异,将ViewModel范围限定为Fragment的ViewLifecycleowner()是解决此问题的好方法吗?

因此要更改此内容:

vm = new ViewModelProvider(this).get(AddInventoryVM.class);

对此:

vm = new ViewModelProvider(getViewLifecycleowner()).get(AddInventoryVM.class);


按照Navigate to a destination documentation:


  

Android会维护一个包含您访问过的目的地的后台堆栈。当用户打开应用程序时,您的应用程序的第一个目标位于堆栈上。每次对navigate()方法的调用都会在栈顶放置另一个目标。

因此,当您调用navController.navigate(R.id.addInventoryFragment,null);时,您是将添加库存片段的全新实例添加到后堆栈中,这意味着您的后堆栈现在有两个副本。如果您再次致电navigate(),则将有3个副本,然后有4个副本,等等。

您可以use popUpTo,或者,如果您知道自己总是用它自己替换片段,请使用setLaunchSingleTop(true)

NavOptions optiOns= new NavOptions.Builder()
.setLaunchSingleTop(true)
.build();
navController.navigate(R.id.addInventoryFragment,null,options);

(如果您使用的是 in Navigation XML,则可以使用app:launchSingleTop="true"做同样的事情)


推荐阅读
author-avatar
手机用户2502929183
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有