您的位置:首页 > 移动开发 > Android开发

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

2017-10-16 14:00 441 查看
内部组会上讲了一下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()。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android