Viewholder内部会议纪要以及fragment相关知识总结

来源:互联网 发布:用js给input赋值 编辑:程序博客网 时间:2024/05/22 13:57

内部组会上讲了一下viewHolder在解耦方面的应用( 使用ViewModel解耦页面(含源码分析))。在讲解和讨论过程中,发现对fragment的一些知识点理解不到位。会后查看了相关的知识点并总结了一下:

使用 Viewholder方式:ViewModelProviders.of(宿主activity).get(A.class) 其中A extend ViewHolder

用处:一个activty内,任何block,adapter,view类中都可“无显式耦合”的获得彼此间的数据。举例:我们可以在activty一开始就存一个movieId的viewHolder,那么这个activty涉及的所有类中都可以使用context来获取movieId。这对于埋点等都是很好帮助的,避免了级联引用。

大致原理:ViewModelProviders.of()用于获取ViewModelProvider实例。ViewModelProvider中含有一个ViewModelStore,ViewModelStore是用来存储viewModel的(ViewModelStore内部含有map)。ViewModelStore对于宿主activity是唯一的。其实质是宿主activity中HoldFragment的一个成员变量。

更正
旋转屏幕时,activty内置的HolderFragment不会被销毁(为什么旋转时不会被销毁,是因为在HolderFragment中指定了setRetainInstance(true);),且fragmentManager.findFragmentByTag(HOLDER_TAG)还是能够找到内置的HolderFragment。
因为HolderFragment中存储map ,所以这就解释了为什么activity在旋转的时候,viewModel不会丢失。

旋转屏幕时,原来的activty会被销毁,重新生成一个新的activty。昨天提到的HolderFragmentManager中map
类型的成员变量mNotCommittedActivityHolders不是为了屏幕旋转问题而生的。他里面对应的Entry的生存时间是“new出来HolderFragment时刻 到HolderFragment执行onCreate()执行完的时刻”,如果HolderFragment始终没有执行onCreate()那么等到activty销毁的时候,会清除mNotCommittedActivityHolders中对应的Entry。既然不是为屏幕旋转问题而生,那为什么要弄个这个呢?因为fragment在commit()以后不会立即执行commit()动作,会使用handler来把这次的commit放到主线程消息队列中,等待执行。所以如果fragment在没有真正执行commit()动作的时候,使用manager.findFragmentByTag(HOLDER_TAG)找不到对应的HolderFragment,那么用mNotCommittedActivityHolders这样方式来兜底。

一些生命周期的执行顺序执行
在Activity中onCreate()中执行addFragent()的commit动作(使用commit()或commitAllowingStateLoss())时,
Activity的onCreate()、
Fragment的onAttach()、
activty的onAttachFragment()、
Fragment的onCreate()的执行顺序:
Activity#onCreate()->
Fragment#onAttach()->
activty#onAttachFragment->
Fragment#onCreate()

源码注释:

     /** * Called when a Fragment is being attached to this activity, immediately * after the call to its {@link Fragment#onAttach Fragment.onAttach()} * method and before {@link Fragment#onCreate Fragment.onCreate()}. */public void Activity#onAttachFragment(Fragment fragment) {}

commit立即执行
使用commitNow()和commitNowAllowingStateLoss()来代替commit()或commitAllowingStateLoss()。或使用commit()/commitAllowingStateLoss()->
executePendingTransactions()
这样不用使用handler分发,而是立即执行。

commit()和commitAllowingStateLoss()区别

在Activity的状态被保存之后(执行了onSaveInstanceState(),这个方法在onStop()之后可能执行),提交commit操作是没有被Activity所记录的,恢复时也就没办法恢复这些提交操作,所以官方文档称这个方法是一个危险的操作。如果这些提交操作不是很重要,丢不丢失无所谓的话你就可以使用commitAllowingStateLoss()这个方法了。
所以如果onSaveInstanceState()之后,再执行commit,那么就会异常,这时候得使用commitAllowingStateLoss()。

原创粉丝点击